<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>React入门到进阶 | 青灯有味</title>
    <meta name="generator" content="VuePress 1.5.4">
    <link rel="manifest" href="/manifest.json">
    <link rel="icon" href="/favicon.png">
    <link rel="apple-touch-icon" href="/icon_vuepress_reco.png">
    <link rel="mask-icon" href="/icon_vuepress_reco.svg" color="#42b983">
    <script language="javascript" type="text/javascript" src="https://cdn.staticfile.org/jquery/1.7.2/jquery.min.js" rel="defer"></script>
    <script language="javascript" type="text/javascript" src="/js/MouseClickEffect.js" rel="defer"></script>
    <meta name="description" content="一款简洁易懂算法博客 & 文档抠细节 & 主题">
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta http-equiv="Cache-Control" content="no-siteapp">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit">
    <meta name="force-rendering" content="webkit">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
    <meta name="theme-color" content="#42b983">
    <meta name="keywords" content="前端算法综合查询，办公软件，threejs3D技术开发，vue和react源码讲解，有技术的文档博客">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="msapplication-TileColor" content="#000000">
    <meta name="baidu-site-verification" content="aO3jmjhVNd">
    <meta name="robots" content="all">
    <meta name="csdn-baidu-search" content="[object Object]">
    <link rel="preload" href="/assets/css/0.styles.1b43475e.css" as="style"><link rel="preload" href="/assets/js/app.3af45ec9.js" as="script"><link rel="preload" href="/assets/js/6.5ffa3a3c.js" as="script"><link rel="preload" href="/assets/js/1.60e80d20.js" as="script"><link rel="preload" href="/assets/js/51.075b2486.js" as="script"><link rel="preload" href="/assets/js/36.10d521da.js" as="script"><link rel="prefetch" href="/assets/js/10.b6c238a7.js"><link rel="prefetch" href="/assets/js/100.6fba9f18.js"><link rel="prefetch" href="/assets/js/101.79004a5d.js"><link rel="prefetch" href="/assets/js/11.a0d3dca2.js"><link rel="prefetch" href="/assets/js/12.9620ec1e.js"><link rel="prefetch" href="/assets/js/13.8a4c99c1.js"><link rel="prefetch" href="/assets/js/14.e828e497.js"><link rel="prefetch" href="/assets/js/15.85265c81.js"><link rel="prefetch" href="/assets/js/16.5b98bba6.js"><link rel="prefetch" href="/assets/js/17.5938af1b.js"><link rel="prefetch" href="/assets/js/18.24afa132.js"><link rel="prefetch" href="/assets/js/19.f978cfa2.js"><link rel="prefetch" href="/assets/js/2.3d790711.js"><link rel="prefetch" href="/assets/js/20.41e409f0.js"><link rel="prefetch" href="/assets/js/21.038c02f6.js"><link rel="prefetch" href="/assets/js/22.4595e0d7.js"><link rel="prefetch" href="/assets/js/23.6fabf12d.js"><link rel="prefetch" href="/assets/js/24.ddfa7ac5.js"><link rel="prefetch" href="/assets/js/25.fe3e21e0.js"><link rel="prefetch" href="/assets/js/26.ba28b685.js"><link rel="prefetch" href="/assets/js/27.29cb30b4.js"><link rel="prefetch" href="/assets/js/28.9dabefed.js"><link rel="prefetch" href="/assets/js/29.b110692c.js"><link rel="prefetch" href="/assets/js/3.b52271f3.js"><link rel="prefetch" href="/assets/js/30.db42d4cb.js"><link rel="prefetch" href="/assets/js/31.fe0769c9.js"><link rel="prefetch" href="/assets/js/32.fe344b91.js"><link rel="prefetch" href="/assets/js/33.09556c3f.js"><link rel="prefetch" href="/assets/js/34.0feada29.js"><link rel="prefetch" href="/assets/js/35.80a05aaf.js"><link rel="prefetch" href="/assets/js/37.bd4e8671.js"><link rel="prefetch" href="/assets/js/38.27cec8e2.js"><link rel="prefetch" href="/assets/js/39.793101dd.js"><link rel="prefetch" href="/assets/js/40.0bb89ca4.js"><link rel="prefetch" href="/assets/js/41.43ba7256.js"><link rel="prefetch" href="/assets/js/42.b8b3fad3.js"><link rel="prefetch" href="/assets/js/43.b4ea7ff2.js"><link rel="prefetch" href="/assets/js/44.5d689375.js"><link rel="prefetch" href="/assets/js/45.8985fca2.js"><link rel="prefetch" href="/assets/js/46.c9058cc0.js"><link rel="prefetch" href="/assets/js/47.0e43c612.js"><link rel="prefetch" href="/assets/js/48.7fe8e1b0.js"><link rel="prefetch" href="/assets/js/49.e8a50151.js"><link rel="prefetch" href="/assets/js/50.d0966268.js"><link rel="prefetch" href="/assets/js/52.104c025b.js"><link rel="prefetch" href="/assets/js/53.3e1d2136.js"><link rel="prefetch" href="/assets/js/54.75b0ddc5.js"><link rel="prefetch" href="/assets/js/55.3a80c259.js"><link rel="prefetch" href="/assets/js/56.491226d3.js"><link rel="prefetch" href="/assets/js/57.69c4f560.js"><link rel="prefetch" href="/assets/js/58.dd690d01.js"><link rel="prefetch" href="/assets/js/59.823f14a2.js"><link rel="prefetch" href="/assets/js/60.ab51afcb.js"><link rel="prefetch" href="/assets/js/61.1b6394d6.js"><link rel="prefetch" href="/assets/js/62.d0bcc3c9.js"><link rel="prefetch" href="/assets/js/63.c6f180d6.js"><link rel="prefetch" href="/assets/js/64.150fa30e.js"><link rel="prefetch" href="/assets/js/65.968b9e9f.js"><link rel="prefetch" href="/assets/js/66.1b43f384.js"><link rel="prefetch" href="/assets/js/67.fb067cd5.js"><link rel="prefetch" href="/assets/js/68.94fb1f43.js"><link rel="prefetch" href="/assets/js/69.366f59a5.js"><link rel="prefetch" href="/assets/js/7.cb2bf59a.js"><link rel="prefetch" href="/assets/js/70.9d543737.js"><link rel="prefetch" href="/assets/js/71.c2bbadfb.js"><link rel="prefetch" href="/assets/js/72.d9ad71c6.js"><link rel="prefetch" href="/assets/js/73.fdf1c18d.js"><link rel="prefetch" href="/assets/js/74.817933e2.js"><link rel="prefetch" href="/assets/js/75.1b84ada9.js"><link rel="prefetch" href="/assets/js/76.171fe943.js"><link rel="prefetch" href="/assets/js/77.02471d2d.js"><link rel="prefetch" href="/assets/js/78.9fbacaa9.js"><link rel="prefetch" href="/assets/js/79.3fe97029.js"><link rel="prefetch" href="/assets/js/8.af082f1e.js"><link rel="prefetch" href="/assets/js/80.fde761f4.js"><link rel="prefetch" href="/assets/js/81.77dc188b.js"><link rel="prefetch" href="/assets/js/82.bff1495c.js"><link rel="prefetch" href="/assets/js/83.26ffd6d9.js"><link rel="prefetch" href="/assets/js/84.b2eb10df.js"><link rel="prefetch" href="/assets/js/85.1437d92a.js"><link rel="prefetch" href="/assets/js/86.a388da50.js"><link rel="prefetch" href="/assets/js/87.07f7923d.js"><link rel="prefetch" href="/assets/js/88.c69c5036.js"><link rel="prefetch" href="/assets/js/89.7f885e62.js"><link rel="prefetch" href="/assets/js/9.d6f341ca.js"><link rel="prefetch" href="/assets/js/90.b2147a7f.js"><link rel="prefetch" href="/assets/js/91.b9378968.js"><link rel="prefetch" href="/assets/js/92.c757373d.js"><link rel="prefetch" href="/assets/js/93.05eba063.js"><link rel="prefetch" href="/assets/js/94.b1a94b72.js"><link rel="prefetch" href="/assets/js/95.a5fb7e7e.js"><link rel="prefetch" href="/assets/js/96.9b6870e4.js"><link rel="prefetch" href="/assets/js/97.353656e1.js"><link rel="prefetch" href="/assets/js/98.e3c62cd7.js"><link rel="prefetch" href="/assets/js/99.e58282f2.js"><link rel="prefetch" href="/assets/js/vendors~flowchart.437a03e9.js">
    <link rel="stylesheet" href="/assets/css/0.styles.1b43475e.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container" data-v-2d5f533b><div data-v-2d5f533b><div id="loader-wrapper" class="loading-wrapper" data-v-d48f4d20 data-v-2d5f533b data-v-2d5f533b><div class="loader-main" data-v-d48f4d20><div data-v-d48f4d20></div><div data-v-d48f4d20></div><div data-v-d48f4d20></div><div data-v-d48f4d20></div></div> <!----> <!----></div> <div class="password-shadow password-wrapper-out" style="display:none;" data-v-64685f0e data-v-2d5f533b data-v-2d5f533b><h3 class="title" style="display:none;" data-v-64685f0e data-v-64685f0e>青灯有味</h3> <!----> <label id="box" class="inputBox" style="display:none;" data-v-64685f0e data-v-64685f0e><input type="password" value="" data-v-64685f0e> <span data-v-64685f0e>Konck! Knock!</span> <button data-v-64685f0e>OK</button></label> <div class="footer" style="display:none;" data-v-64685f0e data-v-64685f0e><span data-v-64685f0e><i class="iconfont reco-theme" data-v-64685f0e></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-64685f0e>vuePress-theme-reco</a></span> <span data-v-64685f0e><i class="iconfont reco-copyright" data-v-64685f0e></i> <a data-v-64685f0e><span data-v-64685f0e>Mr.Zhao</span>
            
          <span data-v-64685f0e>2019 - </span>
          2023
        </a></span></div></div> <div class="hide" data-v-2d5f533b><header class="navbar" data-v-2d5f533b><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="/logo.png" alt="青灯有味" class="logo"> <span class="site-name">青灯有味</span></a> <div class="links"><div class="color-picker"><a class="color-button"><i class="iconfont reco-color"></i></a> <div class="color-picker-menu" style="display:none;"><div class="mode-options"><h4 class="title">Choose mode</h4> <ul class="color-mode-options"><li class="dark">dark</li><li class="auto active">auto</li><li class="light">light</li></ul></div></div></div> <div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-document"></i>
      归档
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/views/sofeware/" class="nav-link"><i class="iconfont undefined"></i>
  Sofeware
</a></li><li class="dropdown-item"><h4>实战项目</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://zscnb.gitee.io/vue-manage" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  Vue项目
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-subitem"><a href="/views/demo/" class="nav-link"><i class="iconfont undefined"></i>
  Demo
</a></li><li class="dropdown-subitem"><a href="/views/project.html" class="nav-link"><i class="iconfont undefined"></i>
  我的项目
</a></li><li class="dropdown-subitem"><a href="https://zscnb.gitee.io/rc-bullets/" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  弹幕演示
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-subitem"><a href="https://zscnb.gitee.io/todolist/" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  vue3-今日任务
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-subitem"><a href="https://zscnb.gitee.io/react-todolist/" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  React-今日任务
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-subitem"><a href="https://zscnb.gitee.io/react-web/" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  React响应式网站
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-subitem"><a href="https://zscnb.gitee.io/carland/" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  React carland
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-category"></i>
      Category
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/categories/blog/" class="nav-link"><i class="iconfont undefined"></i>
  blog
</a></li><li class="dropdown-item"><!----> <a href="/categories/杂集/" class="nav-link"><i class="iconfont undefined"></i>
  杂集
</a></li></ul></div></div><div class="nav-item"><a href="/tag/" class="nav-link"><i class="iconfont reco-tag"></i>
  Tag
</a></div><div class="nav-item"><a href="/timeline/" class="nav-link"><i class="iconfont reco-date"></i>
  TimeLine
</a></div><div class="nav-item"><a href="/views/theme-example.html" class="nav-link"><i class="iconfont reco-friend"></i>
  友人帐
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-other"></i>
      Contact
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://www.jianshu.com/u/b7ced0328a6a" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-jianshu"></i>
  简书
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-item"><!----> <a href="https://blog.csdn.net/weixin_42306796" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-csdn"></i>
  CSDN
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-item"><!----> <a href="https://juejin.im/user/5d39b27b51882504b7121ef5" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-juejin"></i>
  掘金
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul></div></div> <a href="https://github.com/zscnb/blog" target="_blank" rel="noopener noreferrer" class="repo-link"><i class="iconfont reco-github"></i>
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav></div></header> <div class="sidebar-mask" data-v-2d5f533b></div> <aside class="sidebar" data-v-2d5f533b><div class="personal-info-wrapper" data-v-ca798c94 data-v-2d5f533b><img src="/avatar.gif" alt="author-avatar" class="personal-img" data-v-ca798c94> <h3 class="name" data-v-ca798c94>
    Mr.Zhao
  </h3> <div class="num" data-v-ca798c94><div data-v-ca798c94><h3 data-v-ca798c94>23</h3> <h6 data-v-ca798c94>Article</h6></div> <div data-v-ca798c94><h3 data-v-ca798c94>33</h3> <h6 data-v-ca798c94>Tag</h6></div></div> <hr data-v-ca798c94></div> <nav class="nav-links"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-document"></i>
      归档
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/views/sofeware/" class="nav-link"><i class="iconfont undefined"></i>
  Sofeware
</a></li><li class="dropdown-item"><h4>实战项目</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://zscnb.gitee.io/vue-manage" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  Vue项目
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-subitem"><a href="/views/demo/" class="nav-link"><i class="iconfont undefined"></i>
  Demo
</a></li><li class="dropdown-subitem"><a href="/views/project.html" class="nav-link"><i class="iconfont undefined"></i>
  我的项目
</a></li><li class="dropdown-subitem"><a href="https://zscnb.gitee.io/rc-bullets/" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  弹幕演示
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-subitem"><a href="https://zscnb.gitee.io/todolist/" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  vue3-今日任务
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-subitem"><a href="https://zscnb.gitee.io/react-todolist/" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  React-今日任务
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-subitem"><a href="https://zscnb.gitee.io/react-web/" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  React响应式网站
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-subitem"><a href="https://zscnb.gitee.io/carland/" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont undefined"></i>
  React carland
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-category"></i>
      Category
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/categories/blog/" class="nav-link"><i class="iconfont undefined"></i>
  blog
</a></li><li class="dropdown-item"><!----> <a href="/categories/杂集/" class="nav-link"><i class="iconfont undefined"></i>
  杂集
</a></li></ul></div></div><div class="nav-item"><a href="/tag/" class="nav-link"><i class="iconfont reco-tag"></i>
  Tag
</a></div><div class="nav-item"><a href="/timeline/" class="nav-link"><i class="iconfont reco-date"></i>
  TimeLine
</a></div><div class="nav-item"><a href="/views/theme-example.html" class="nav-link"><i class="iconfont reco-friend"></i>
  友人帐
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-other"></i>
      Contact
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://www.jianshu.com/u/b7ced0328a6a" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-jianshu"></i>
  简书
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-item"><!----> <a href="https://blog.csdn.net/weixin_42306796" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-csdn"></i>
  CSDN
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li><li class="dropdown-item"><!----> <a href="https://juejin.im/user/5d39b27b51882504b7121ef5" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-juejin"></i>
  掘金
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul></div></div> <a href="https://github.com/zscnb/blog" target="_blank" rel="noopener noreferrer" class="repo-link"><i class="iconfont reco-github"></i>
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav> <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>久然前端算法扫盲博客</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/views/blog/" aria-current="page" class="sidebar-link">介绍</a></li><li><a href="/views/blog/algorithm.html" class="sidebar-link">算法必会篇</a></li><li><a href="/views/blog/design-modes.html" class="sidebar-link">设计模式</a></li><li><a href="/views/blog/leetcode.html" class="sidebar-link">leetcode题库</a></li><li><a href="/views/blog/Sao-operation.html" class="sidebar-link">JavaScript骚操作</a></li><li><a href="/views/blog/Source-code.html" class="sidebar-link">源码解析前端两大框架</a></li><li><a href="/views/blog/Front-end-optimization.html" class="sidebar-link">前端页面优化</a></li><li><a href="/views/blog/compoments.html" class="sidebar-link">组件库开发和发布</a></li><li><a href="/views/blog/react-base.html" aria-current="page" class="active sidebar-link">React入门到进阶</a></li><li><a href="/views/blog/react-framework.html" class="sidebar-link">React入门篇</a></li><li><a href="/views/blog/react-obtain.html" class="sidebar-link">React就业篇</a></li><li><a href="/views/blog/vue3base.html" class="sidebar-link">Vue3基本教程</a></li><li><a href="/views/blog/vue3study.html" class="sidebar-link">vue3知识梳理</a></li><li><a href="/views/blog/vuestudy.html" class="sidebar-link">学习vue常用知识点</a></li><li><a href="/views/blog/vuex.html" class="sidebar-link">Vuex</a></li><li><a href="/views/blog/Vue_performance_optimization.html" class="sidebar-link">Vue性能优化九法</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>互动3D技术</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>Webpack</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>Echarts</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <div class="password-shadow password-wrapper-in" style="display:none;" data-v-64685f0e data-v-2d5f533b><h3 class="title" style="display:none;" data-v-64685f0e data-v-64685f0e>React入门到进阶</h3> <!----> <label id="box" class="inputBox" style="display:none;" data-v-64685f0e data-v-64685f0e><input type="password" value="" data-v-64685f0e> <span data-v-64685f0e>Konck! Knock!</span> <button data-v-64685f0e>OK</button></label> <div class="footer" style="display:none;" data-v-64685f0e data-v-64685f0e><span data-v-64685f0e><i class="iconfont reco-theme" data-v-64685f0e></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-64685f0e>vuePress-theme-reco</a></span> <span data-v-64685f0e><i class="iconfont reco-copyright" data-v-64685f0e></i> <a data-v-64685f0e><span data-v-64685f0e>Mr.Zhao</span>
            
          <span data-v-64685f0e>2019 - </span>
          2023
        </a></span></div></div> <div data-v-2d5f533b><main class="page"><div class="page-title" style="display:none;"><h1 class="title">React入门到进阶</h1> <div data-v-3b7f5bdf><i class="iconfont reco-account" data-v-3b7f5bdf><span data-v-3b7f5bdf>Mr.Zhao</span></i> <i class="iconfont reco-date" data-v-3b7f5bdf><span data-v-3b7f5bdf>2022-09-24 16:16:45</span></i> <i class="iconfont reco-eye" data-v-3b7f5bdf><span id="/views/blog/react-base.html" data-flag-title="Your Article Title" class="leancloud-visitors" data-v-3b7f5bdf><a class="leancloud-visitors-count" style="font-size:.9rem;font-weight:normal;color:#999;"></a></span></i> <i class="iconfont reco-tag tags" data-v-3b7f5bdf><span class="tag-item" data-v-3b7f5bdf>重点</span><span class="tag-item" data-v-3b7f5bdf>难点</span><span class="tag-item" data-v-3b7f5bdf>原创</span></i></div></div> <div class="theme-reco-content content__default" style="display:none;"><h2 id="react-介绍"><a href="#react-介绍" class="header-anchor">#</a> React 介绍</h2> <p>目标任务: 了解什么是 React 以及它的特点</p> <h3 id="react-是什么"><a href="#react-是什么" class="header-anchor">#</a> React 是什么</h3> <p>一个专注于构建用户界面的 JavaScript 库，和 vue 和 angular 并称前端三大框架，不夸张的说，
react 引领了很多新思想，世界范围内是最流行的 js 前端框架，最近发布了 18 版本，加入了很多新特性</p> <p><a href="https://reactjs.org/" target="_blank" rel="noopener noreferrer">React 英文文档<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <p><a href="https://zh-hans.reactjs.org/" target="_blank" rel="noopener noreferrer">React 中文文档<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <p><a href="https://beta.reactjs.org/" target="_blank" rel="noopener noreferrer">React 新文档 <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>（开发中....）</p> <h3 id="react-有什么特点"><a href="#react-有什么特点" class="header-anchor">#</a> React 有什么特点</h3> <ul><li>1- 声明式 UI（JSX）
<blockquote><p>写 UI 就和写普通的 HTML 一样，抛弃命令式的繁琐实现</p></blockquote></li></ul> <p><img src="http://zscnb.gitee.io/upload/static/img/compare.png" draggable="false" alt="image-20201026174611477"></p> <ul><li><p>2- 组件化</p> <blockquote><p>组件是 react 中最重要的内容，组件可以通过搭积木的方式拼成一个完整的页面，通过组件的抽象可以增加复用能力和提高可维护性</p></blockquote></li></ul> <p><img src="http://zscnb.gitee.io/upload/static/img/image.png" draggable="false" alt="image-20201026174611477"></p> <ul><li>3- 跨平台</li></ul> <blockquote><p>react 既可以开发 web 应用也可以使用同样的语法开发原生应用（react-native），比如安卓和 ios 应用，甚至可以使用 react 开发 VR 应用，想象力空间十 足， react 更像是一个 元框架 为各种领域赋能</p></blockquote> <h2 id="环境初始化"><a href="#环境初始化" class="header-anchor">#</a> 环境初始化</h2> <p><code>目标任务:</code> 能够独立使用 React 脚手架创建一个 react 项目</p> <h3 id="使用脚手架创建项目"><a href="#使用脚手架创建项目" class="header-anchor">#</a> <strong>使用脚手架创建项目</strong></h3> <ul><li>打开命令行窗口</li> <li>执行命令</li></ul> <div class="language-bash extra-class"><pre class="language-bash"><code> npx create-react-app react-basic
</code></pre></div><p><strong>说明：</strong></p> <p>a. npx create-react-app 是固定命令，create-react-app 是 React 脚手架的名称</p> <p>b. react-basic 表示项目名称，可以自定义，保持语义化</p> <p>c. npx 命令会帮助我们临时安装 create-react-app 包，然后初始化项目完成之后会自自动删掉，所以不需要全局安装 create-react-app</p> <p><strong>启动项目</strong></p> <div class="language-sh extra-class"><pre class="language-sh"><code><span class="token function">yarn</span> start
or
<span class="token function">npm</span> start
</code></pre></div><h3 id="项目目录说明调整"><a href="#项目目录说明调整" class="header-anchor">#</a> <strong>项目目录说明调整</strong></h3> <p>● <code>目录说明</code></p> <p>a. src 目录是我们写代码进行项目开发的目录</p> <p>b. package.json 中俩个核心库：react 、react-dom</p> <p>● <code>目录调整</code></p> <p>a. 删除 src 目录下自带的所有文件，只保留 app.js 根组件和 index.js</p> <p>b. 创建 index.js 文件作为项目的入口文件，在这个文件中书写 react 代码即可</p> <p>● <code>入口文件说明</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">import</span> ReactDOM <span class="token keyword">from</span> <span class="token string">'react-dom'</span>
<span class="token keyword">import</span> <span class="token string">'./index.css'</span>
<span class="token comment">// 引入根组件App</span>
<span class="token keyword">import</span> App <span class="token keyword">from</span> <span class="token string">'./App'</span>
<span class="token comment">// 通过调用ReactDOM的render方法渲染App根组件到id为root的dom节点上</span>
ReactDOM<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">React.StrictMode</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">App</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">React.StrictMode</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">,</span>
  document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'root'</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span>
</code></pre></div><h2 id="jsx-基础"><a href="#jsx-基础" class="header-anchor">#</a> JSX 基础</h2> <h3 id="_1-jsx-介绍"><a href="#_1-jsx-介绍" class="header-anchor">#</a> 1. JSX 介绍</h3> <p><code>目标任务</code>: 能够理解什么是 JSX，JSX 的底层是什么</p> <p>概念：JSX 是 JavaScript XML（HTML）的缩写，表示在 JS 代码中书写 HTML 结构
作用：在 React 中创建 HTML 结构（页面 UI 结构）
优势：</p> <ol><li>采用类似于 HTML 的语法，降低学习成本，会 HTML 就会 JSX</li> <li>充分利用 JS 自身的可编程能力创建 HTML 结构</li></ol> <p>注意：JSX 并不是标准的 JS 语法，是 JS 的语法扩展，浏览器默认是不识别的，脚手架中内置的 <code>@babel/plugin-transform-react-jsx</code> 包，用来解析该语法</p> <p><img src="http://zscnb.gitee.io/upload/static/img/jsx02.png" draggable="false" alt="image-20201026174611477"></p> <h3 id="_2-jsx-中使用-js-表达式"><a href="#_2-jsx-中使用-js-表达式" class="header-anchor">#</a> 2. JSX 中使用 js 表达式</h3> <p><code>目标任务</code>: 能够在 JSX 中使用表达式</p> <p>语法
<strong><code>{ JS 表达式 }</code></strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">const</span> name <span class="token operator">=</span> <span class="token string">'柴柴'</span>


<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">你好，我叫</span><span class="token punctuation">{</span>name<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span>   <span class="token comment">//  &lt;h1&gt;你好,我叫柴柴&lt;/h1&gt;</span>
</code></pre></div><p><strong>可以使用的表达式,<code>有值</code>的语句</strong></p> <div class="language-sh extra-class"><pre class="language-sh"><code><span class="token number">1</span>. 字符串、数值、布尔值、null、undefined、object（ <span class="token punctuation">[</span><span class="token punctuation">]</span> / <span class="token punctuation">{</span><span class="token punctuation">}</span> ）
<span class="token number">2</span>. <span class="token number">1</span> + <span class="token number">2</span>、<span class="token string">'abc'</span>.split<span class="token punctuation">(</span><span class="token string">''</span><span class="token punctuation">)</span>、<span class="token punctuation">[</span><span class="token string">'a'</span>, <span class="token string">'b'</span><span class="token punctuation">]</span>.join<span class="token punctuation">(</span><span class="token string">'-'</span><span class="token punctuation">)</span>
<span class="token number">3</span>. fn<span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre></div><p><strong>特别注意</strong></p> <blockquote><p>if 语句/ switch-case 语句/ 变量声明语句，这些叫做语句，不是表达式，不能出现在 {} 中！！</p></blockquote> <h3 id="_3-jsx-列表渲染"><a href="#_3-jsx-列表渲染" class="header-anchor">#</a> 3. JSX 列表渲染</h3> <p>目标任务: 能够在 JSX 中实现列表渲染
页面的构建离不开重复的列表结构，比如歌曲列表，商品列表等，我们知道 vue 中用的是 v-for，react 这边如何实现呢？</p> <p>实现：使用数组的 map 方法</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 来个列表</span>
<span class="token keyword">const</span> songs <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span> id<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> name<span class="token operator">:</span> <span class="token string">'痴心绝对'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> id<span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> name<span class="token operator">:</span> <span class="token string">'像我这样的人'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> id<span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> name<span class="token operator">:</span> <span class="token string">'南山南'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span>songs<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>item<span class="token punctuation">.</span>name<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
        <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><p>注意点：需要为遍历项添加 key 属性</p> <p><img src="http://zscnb.gitee.io/upload/static/img/jsx03.png" draggable="false" alt="image-20201026174611477"></p> <ol><li>key 在 HTML 结构中是看不到的，是 React 内部用来进行性能优化时使用</li> <li>key 在当前列表中要唯一的字符串或者数值（String/Number）</li> <li>如果列表中有像 id 这种的唯一值，就用 id 来作为 key 值</li> <li>如果列表中没有像 id 这种的唯一值，就可以使用 index（下标）来作为 key 值</li></ol> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 来个列表</span>
<span class="token keyword">const</span> songs <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span> id<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> name<span class="token operator">:</span> <span class="token string">'痴心绝对'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> id<span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> name<span class="token operator">:</span> <span class="token string">'像我这样的人'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> id<span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> name<span class="token operator">:</span> <span class="token string">'南山南'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span>songs<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
          <span class="token comment">// 如果列表中有像 id 这种的唯一值，就用 id 来作为 key 值</span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>item<span class="token punctuation">.</span>id<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>item<span class="token punctuation">.</span>name<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
        <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h3 id="_4-jsx-条件渲染"><a href="#_4-jsx-条件渲染" class="header-anchor">#</a> 4. JSX 条件渲染</h3> <p><code>目标任务</code>: 能够在 JSX 中实现条件渲染</p> <p>作用：根据是否满足条件生成 HTML 结构，比如 Loading 效果</p> <p>实现：可以使用 三元运算符 或 逻辑与(&amp;&amp;)运算符</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 来个布尔值</span>
<span class="token keyword">const</span> flag <span class="token operator">=</span> <span class="token boolean">true</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token comment">/* 条件渲染字符串 */</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token punctuation">{</span>flag <span class="token operator">?</span> <span class="token string">'react真有趣'</span> <span class="token operator">:</span> <span class="token string">'vue真有趣'</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token comment">/* 条件渲染标签/组件 */</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token punctuation">{</span>flag <span class="token operator">?</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">this is span</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span> <span class="token operator">:</span> <span class="token keyword">null</span><span class="token punctuation">}</span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h3 id="_5-jsx-样式处理"><a href="#_5-jsx-样式处理" class="header-anchor">#</a> 5. JSX 样式处理</h3> <p><code>目标任务</code>: 能够在 JSX 中实现 css 样式处理</p> <p>● 行内样式 - style</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> color<span class="token operator">:</span> <span class="token string">'red'</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">this is a div</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><p>● 行内样式 - style - 更优写法</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">const</span> styleObj <span class="token operator">=</span> <span class="token punctuation">{</span>
  color<span class="token operator">:</span> red<span class="token punctuation">,</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>styleObj<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">this is a div</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><p>● 类名 - className（推荐）</p> <div class="language-css extra-class"><pre class="language-css"><code><span class="token selector">.title</span> <span class="token punctuation">{</span>
  <span class="token property">font-size</span><span class="token punctuation">:</span> 30px<span class="token punctuation">;</span>
  <span class="token property">color</span><span class="token punctuation">:</span> blue<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>● 类名 - className - 动态类名控制</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token string">'./app.css'</span>
<span class="token keyword">const</span> showTitle <span class="token operator">=</span> <span class="token boolean">true</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>showTitle <span class="token operator">?</span> <span class="token string">'title'</span> <span class="token operator">:</span> <span class="token string">''</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">this is a div</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h3 id="_6-jsx-注意事项"><a href="#_6-jsx-注意事项" class="header-anchor">#</a> 6. JSX 注意事项</h3> <p><code>目标任务</code>: 掌握 JSX 在实际应用时的注意事项</p> <ol><li>JSX 必须有一个根节点，如果没有根节点，可以使用&lt;&gt;&lt;/&gt;（幽灵节点）替代</li> <li>所有标签必须形成闭合，成对闭合或者自闭合都可以</li> <li>JSX 中的语法更加贴近 JS 语法，属性名采用驼峰命名法 class -&gt; className for -&gt; htmlFor</li> <li>JSX 支持多行（换行），如果需要换行，需使用() 包裹，防止 bug 出现</li></ol> <p><strong>格式化配置</strong></p> <p>目标任务: 基于 vscode 配置格式化工具，提高开发效率</p> <ol><li>安装 vsCode prettier 插件</li> <li>修改配置文件 setting.json</li></ol> <div class="language-json extra-class"><pre class="language-json"><code><span class="token punctuation">{</span>
  <span class="token property">&quot;git.enableSmartCommit&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token comment">// 修改注释颜色</span>
  <span class="token property">&quot;editor.tokenColorCustomizations&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">&quot;comments&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token property">&quot;fontStyle&quot;</span><span class="token operator">:</span> <span class="token string">&quot;bold&quot;</span><span class="token punctuation">,</span>
      <span class="token property">&quot;foreground&quot;</span><span class="token operator">:</span> <span class="token string">&quot;#82e0aa&quot;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token comment">// 配置文件类型识别</span>
  <span class="token property">&quot;files.associations&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">&quot;*.js&quot;</span><span class="token operator">:</span> <span class="token string">&quot;javascript&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;*.json&quot;</span><span class="token operator">:</span> <span class="token string">&quot;jsonc&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;*.cjson&quot;</span><span class="token operator">:</span> <span class="token string">&quot;jsonc&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;*.wxss&quot;</span><span class="token operator">:</span> <span class="token string">&quot;css&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;*.wxs&quot;</span><span class="token operator">:</span> <span class="token string">&quot;javascript&quot;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token property">&quot;extensions.ignoreRecommendations&quot;</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
  <span class="token property">&quot;files.exclude&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">&quot;**/.DS_Store&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
    <span class="token property">&quot;**/.git&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
    <span class="token property">&quot;**/.hg&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
    <span class="token property">&quot;**/.svn&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
    <span class="token property">&quot;**/CVS&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
    <span class="token property">&quot;**/node_modules&quot;</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
    <span class="token property">&quot;**/tmp&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token comment">// &quot;javascript.implicitProjectConfig.experimentalDecorators&quot;: true,</span>
  <span class="token property">&quot;explorer.confirmDragAndDrop&quot;</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
  <span class="token property">&quot;typescript.updateImportsOnFileMove.enabled&quot;</span><span class="token operator">:</span> <span class="token string">&quot;prompt&quot;</span><span class="token punctuation">,</span>
  <span class="token property">&quot;git.confirmSync&quot;</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
  <span class="token property">&quot;editor.tabSize&quot;</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
  <span class="token property">&quot;editor.fontWeight&quot;</span><span class="token operator">:</span> <span class="token string">&quot;500&quot;</span><span class="token punctuation">,</span>
  <span class="token property">&quot;[json]&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token property">&quot;editor.tabCompletion&quot;</span><span class="token operator">:</span> <span class="token string">&quot;on&quot;</span><span class="token punctuation">,</span>
  <span class="token property">&quot;vsicons.projectDetection.autoReload&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token property">&quot;editor.fontFamily&quot;</span><span class="token operator">:</span> <span class="token string">&quot;Monaco, 'Courier New', monospace, Meslo LG M for Powerline&quot;</span><span class="token punctuation">,</span>
  <span class="token property">&quot;[html]&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">&quot;editor.defaultFormatter&quot;</span><span class="token operator">:</span> <span class="token string">&quot;vscode.html-language-features&quot;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token property">&quot;editor.fontSize&quot;</span><span class="token operator">:</span> <span class="token number">16</span><span class="token punctuation">,</span>
  <span class="token property">&quot;debug.console.fontSize&quot;</span><span class="token operator">:</span> <span class="token number">14</span><span class="token punctuation">,</span>
  <span class="token property">&quot;vsicons.dontShowNewVersionMessage&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token property">&quot;editor.minimap.enabled&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token property">&quot;emmet.extensionsPath&quot;</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">&quot;&quot;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token comment">// vue eslint start 保存时自动格式化代码</span>
  <span class="token property">&quot;editor.formatOnSave&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token comment">// eslint配置项，保存时自动修复错误</span>
  <span class="token property">&quot;editor.codeActionsOnSave&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">&quot;source.fixAll&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token property">&quot;vetur.ignoreProjectWarning&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token comment">// 让vetur使用vs自带的js格式化工具</span>
  <span class="token comment">// uni-app和vue 项目使用</span>
  <span class="token property">&quot;vetur.format.defaultFormatter.js&quot;</span><span class="token operator">:</span> <span class="token string">&quot;vscode-typescript&quot;</span><span class="token punctuation">,</span>
  <span class="token property">&quot;javascript.format.semicolons&quot;</span><span class="token operator">:</span> <span class="token string">&quot;remove&quot;</span><span class="token punctuation">,</span>
  <span class="token comment">// // 指定 *.vue 文件的格式化工具为vetur</span>
  <span class="token property">&quot;[vue]&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">&quot;editor.defaultFormatter&quot;</span><span class="token operator">:</span> <span class="token string">&quot;octref.vetur&quot;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token comment">// // 指定 *.js 文件的格式化工具为vscode自带</span>
  <span class="token property">&quot;[javascript]&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">&quot;editor.defaultFormatter&quot;</span><span class="token operator">:</span> <span class="token string">&quot;vscode.typescript-language-features&quot;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token comment">// // 默认使用prettier格式化支持的文件</span>
  <span class="token property">&quot;editor.defaultFormatter&quot;</span><span class="token operator">:</span> <span class="token string">&quot;esbenp.prettier-vscode&quot;</span><span class="token punctuation">,</span>
  <span class="token property">&quot;prettier.jsxBracketSameLine&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token comment">// 函数前面加个空格</span>
  <span class="token property">&quot;javascript.format.insertSpaceBeforeFunctionParenthesis&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token property">&quot;prettier.singleQuote&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token property">&quot;prettier.semi&quot;</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
  <span class="token comment">// eslint end</span>
  <span class="token comment">// react</span>
  <span class="token comment">// 当按tab键的时候，会自动提示</span>
  <span class="token property">&quot;emmet.triggerExpansionOnTab&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token property">&quot;emmet.showAbbreviationSuggestions&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token property">&quot;emmet.includeLanguages&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token comment">// jsx的提示</span>
    <span class="token property">&quot;javascript&quot;</span><span class="token operator">:</span> <span class="token string">&quot;javascriptreact&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;vue-html&quot;</span><span class="token operator">:</span> <span class="token string">&quot;html&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;vue&quot;</span><span class="token operator">:</span> <span class="token string">&quot;html&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;wxml&quot;</span><span class="token operator">:</span> <span class="token string">&quot;html&quot;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token comment">// end</span>
  <span class="token property">&quot;[jsonc]&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">&quot;editor.defaultFormatter&quot;</span><span class="token operator">:</span> <span class="token string">&quot;vscode.json-language-features&quot;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token comment">// @路径提示</span>
  <span class="token property">&quot;path-intellisense.mappings&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">&quot;@&quot;</span><span class="token operator">:</span> <span class="token string">&quot;${workspaceRoot}/src&quot;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token property">&quot;security.workspace.trust.untrustedFiles&quot;</span><span class="token operator">:</span> <span class="token string">&quot;open&quot;</span><span class="token punctuation">,</span>
  <span class="token property">&quot;git.ignoreMissingGitWarning&quot;</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token property">&quot;window.zoomLevel&quot;</span><span class="token operator">:</span> <span class="token number">1</span>
<span class="token punctuation">}</span>
</code></pre></div><div style="font-size:40px;font-weight:bloder;margin:50px 0;">深入 JSX </div> <p><a href="https://zh-hans.reactjs.org/docs/jsx-in-depth.html" target="_blank" rel="noopener noreferrer">文档 JSX React 官网获取<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <p>实际上，JSX 仅仅只是 <code>React.createElement(component, props, ...children)</code> 函数的语法糖。如下 JSX 代码：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>MyButton color<span class="token operator">=</span><span class="token string">&quot;blue&quot;</span> shadowSize<span class="token operator">=</span><span class="token punctuation">{</span><span class="token number">2</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>
  Click Me
<span class="token operator">&lt;</span><span class="token operator">/</span>MyButton<span class="token operator">&gt;</span>
</code></pre></div><p>会编译为：</p> <div class="language-js extra-class"><pre class="language-js"><code>React<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span>MyButton<span class="token punctuation">,</span> <span class="token punctuation">{</span> color<span class="token operator">:</span> <span class="token string">'blue'</span><span class="token punctuation">,</span> shadowSize<span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">'Click Me'</span><span class="token punctuation">)</span>
</code></pre></div><p>如果没有子节点，你还可以使用<code>自闭合</code>的标签形式，如：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>div className<span class="token operator">=</span><span class="token string">&quot;sidebar&quot;</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
</code></pre></div><p>会编译为:</p> <div class="language-js extra-class"><pre class="language-js"><code>React<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> className<span class="token operator">:</span> <span class="token string">'sidebar'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>如果你想测试一些特定的 JSX 会转换成什么样的 JavaScript，你可以尝试使用 <a href="https://zh.wikipedia.org/wiki/%E7%89%9B%E9%A1%BF%E8%BF%90%E5%8A%A8%E5%AE%9A%E5%BE%8B" target="_blank" rel="noopener noreferrer">在线的 Babel 编译器<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>。</p> <h2 id="jsx-指定-react-元素类型"><a href="#jsx-指定-react-元素类型" class="header-anchor">#</a> JSX 指定 React 元素类型</h2> <p>JSX 标签的第一部分指定了 React 元素的类型。</p> <p>大写字母开头的 JSX 标签意味着它们是 React 组件。这些标签会被编译为对命名变量的直接引用，所以，当你使用 JSX <code>&lt;Foo /&gt;</code> 表达式时，<code>Foo</code> 必须包含在作用域内。</p> <h3 id="react-必须在作用域内"><a href="#react-必须在作用域内" class="header-anchor">#</a> React 必须在作用域内</h3> <p>由于 JSX 会编译为 <code>React.createElement</code> 调用形式，所以 <code>React</code> 库也必须包含在 JSX 代码作用域内。</p> <p>例如，在如下代码中，虽然 <code>React</code> 和 <code>CustomButton</code> 并没有被直接使用，但还是需要导入：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">import</span> CustomButton <span class="token keyword">from</span> <span class="token string">'./CustomButton'</span>

<span class="token keyword">function</span> <span class="token function">WarningButton</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// return React.createElement(CustomButton, {color: 'red'}, null);</span>
  <span class="token keyword">return</span> <span class="token operator">&lt;</span>CustomButton color<span class="token operator">=</span><span class="token string">&quot;red&quot;</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>如果你不使用 JavaScript 打包工具而是直接通过 <code>&lt;script&gt;</code> 标签加载 React，则必须将 <code>React</code> 挂载到全局变量中。</p> <h3 id="在-jsx-类型中使用点语法-对象"><a href="#在-jsx-类型中使用点语法-对象" class="header-anchor">#</a> 在 JSX 类型中使用点语法(对象)</h3> <p>在 JSX 中，你也可以使用点语法来引用一个 React 组件。当你在一个模块中导出许多 React 组件时，这会非常方便。例如，如果 <code>MyComponents.DatePicker</code> 是一个组件，你可以在 JSX 中直接使用：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token keyword">const</span> MyComponents <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token function-variable function">DatePicker</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token function">DatePicker</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token operator">&lt;</span>div<span class="token operator">&gt;</span>Imagine a <span class="token punctuation">{</span>props<span class="token punctuation">.</span>color<span class="token punctuation">}</span> datepicker here<span class="token punctuation">.</span><span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">BlueDatePicker</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token operator">&lt;</span>MyComponents<span class="token punctuation">.</span>DatePicker color<span class="token operator">=</span><span class="token string">&quot;blue&quot;</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="用户定义的组件必须以大写字母开头"><a href="#用户定义的组件必须以大写字母开头" class="header-anchor">#</a> 用户定义的组件必须以大写字母开头</h3> <p>以小写字母开头的元素代表一个 HTML 内置组件，比如 <code>&lt;div&gt;</code> 或者 <code>&lt;span&gt;</code> 会生成相应的字符串 <code>'div'</code> 或者 <code>'span'</code> 传递给 <code>React.createElement</code>（作为参数）。大写字母开头的元素则对应着在 JavaScript 引入或自定义的组件，如 <code>&lt;Foo /&gt;</code> 会编译为 <code>React.createElement(Foo)</code>。</p> <p>我们建议使用大写字母开头命名自定义组件。如果你确实需要一个以小写字母开头的组件，则在 JSX 中使用它之前，必须将它赋值给一个大写字母开头的变量。</p> <p>例如，以下的代码将无法按照预期运行：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token comment">// 错误！组件应该以大写字母开头：</span>
<span class="token keyword">function</span> <span class="token function">hello</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 正确！这种 &lt;div&gt; 的使用是合法的，因为 div 是一个有效的 HTML 标签</span>
  <span class="token keyword">return</span> <span class="token operator">&lt;</span>div<span class="token operator">&gt;</span>Hello <span class="token punctuation">{</span>props<span class="token punctuation">.</span>toWhat<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">HelloWorld</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 错误！React 会认为 &lt;hello /&gt; 是一个 HTML 标签，因为它没有以大写字母开头：</span>
  <span class="token keyword">return</span> <span class="token operator">&lt;</span>hello toWhat<span class="token operator">=</span><span class="token string">&quot;World&quot;</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>要解决这个问题，我们需要重命名 <code>hello</code> 为 <code>Hello</code>，同时在 JSX 中使用 <code>&lt;Hello /&gt;</code> ：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token comment">// 正确！组件需要以大写字母开头：</span>
<span class="token keyword">function</span> <span class="token function">Hello</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 正确！ 这种 &lt;div&gt; 的使用是合法的，因为 div 是一个有效的 HTML 标签：</span>
  <span class="token keyword">return</span> <span class="token operator">&lt;</span>div<span class="token operator">&gt;</span>Hello <span class="token punctuation">{</span>props<span class="token punctuation">.</span>toWhat<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">HelloWorld</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 正确！React 知道 &lt;Hello /&gt; 是一个组件，因为它是大写字母开头的：</span>
  <span class="token keyword">return</span> <span class="token operator">&lt;</span>Hello toWhat<span class="token operator">=</span><span class="token string">&quot;World&quot;</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="在运行时选择类型"><a href="#在运行时选择类型" class="header-anchor">#</a> 在运行时选择类型</h3> <p>你不能将通用表达式作为 React 元素类型。如果你想通过通用表达式来（动态）决定元素类型，你需要首先将它赋值给大写字母开头的变量。这通常用于根据 prop 来渲染不同组件的情况下:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> PhotoStory<span class="token punctuation">,</span> VideoStory <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'./stories'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> components <span class="token operator">=</span> <span class="token punctuation">{</span>
photo<span class="token operator">:</span> PhotoStory<span class="token punctuation">,</span>
video<span class="token operator">:</span> VideoStory
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">Story</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// 错误！JSX 类型不能是一个表达式。</span>
<span class="token keyword">return</span> <span class="token operator">&lt;</span>components<span class="token punctuation">[</span>props<span class="token punctuation">.</span>storyType<span class="token punctuation">]</span> story<span class="token operator">=</span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>story<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>要解决这个问题, 需要首先将类型赋值给一个<code>大写字母</code>开头的变量：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> PhotoStory<span class="token punctuation">,</span> VideoStory <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'./stories'</span>

<span class="token keyword">const</span> components <span class="token operator">=</span> <span class="token punctuation">{</span>
  photo<span class="token operator">:</span> PhotoStory<span class="token punctuation">,</span>
  video<span class="token operator">:</span> VideoStory<span class="token punctuation">,</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">Story</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 正确！JSX 类型可以是大写字母开头的变量。</span>
  <span class="token keyword">const</span> SpecificStory <span class="token operator">=</span> components<span class="token punctuation">[</span>props<span class="token punctuation">.</span>storyType<span class="token punctuation">]</span>
  <span class="token keyword">return</span> <span class="token operator">&lt;</span>SpecificStory story<span class="token operator">=</span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>story<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="jsx-中的-props"><a href="#jsx-中的-props" class="header-anchor">#</a> JSX 中的 Props</h2> <p>有多种方式可以在 JSX 中指定 props。</p> <h3 id="javascript-表达式作为-props"><a href="#javascript-表达式作为-props" class="header-anchor">#</a> JavaScript 表达式作为 Props</h3> <p>你可以把包裹在 <code>{}</code> 中的 JavaScript 表达式作为一个 prop 传递给 JSX 元素。例如，如下的 JSX：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>MyComponent foo<span class="token operator">=</span><span class="token punctuation">{</span><span class="token number">1</span> <span class="token operator">+</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token number">3</span> <span class="token operator">+</span> <span class="token number">4</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
</code></pre></div><p>在 <code>MyComponent</code> 中，<code>props.foo</code> 的值等于 <code>1 + 2 + 3 + 4</code> 的执行结果 <code>10</code>。</p> <p><code>if</code> 语句以及 <code>for</code> 循环不是 JavaScript 表达式，所以不能在 JSX 中直接使用。但是，你可以用在 JSX 以外的代码中。比如：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">NumberDescriber</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">let</span> description
  <span class="token keyword">if</span> <span class="token punctuation">(</span>props<span class="token punctuation">.</span>number <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    description <span class="token operator">=</span> <span class="token operator">&lt;</span>strong<span class="token operator">&gt;</span>even<span class="token operator">&lt;</span><span class="token operator">/</span>strong<span class="token operator">&gt;</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    description <span class="token operator">=</span> <span class="token operator">&lt;</span>i<span class="token operator">&gt;</span>odd<span class="token operator">&lt;</span><span class="token operator">/</span>i<span class="token operator">&gt;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token operator">&lt;</span>div<span class="token operator">&gt;</span>
      <span class="token punctuation">{</span>props<span class="token punctuation">.</span>number<span class="token punctuation">}</span> is an <span class="token punctuation">{</span>description<span class="token punctuation">}</span> number
    <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="字符串字面量"><a href="#字符串字面量" class="header-anchor">#</a> 字符串字面量</h3> <p>你可以将字符串字面量赋值给 prop。如下两个 JSX 表达式是等价的：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>MyComponent message<span class="token operator">=</span><span class="token string">&quot;hello world&quot;</span> <span class="token operator">/</span><span class="token operator">&gt;</span>

<span class="token operator">&lt;</span>MyComponent message<span class="token operator">=</span><span class="token punctuation">{</span><span class="token string">'hello world'</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
</code></pre></div><p>当你将字符串字面量赋值给 prop 时，它的值是未转义的。所以，以下两个 JSX 表达式是等价的：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>MyComponent message<span class="token operator">=</span><span class="token string">&quot;&amp;lt;3&quot;</span> <span class="token operator">/</span><span class="token operator">&gt;</span>

<span class="token operator">&lt;</span>MyComponent message<span class="token operator">=</span><span class="token punctuation">{</span><span class="token string">'&lt;3'</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
</code></pre></div><p>这种行为通常是不重要的，这里只是提醒有这个用法。</p> <h3 id="props-默认值为-true"><a href="#props-默认值为-true" class="header-anchor">#</a> Props 默认值为 “True”</h3> <p>如果你没给 prop 赋值，它的默认值是 <code>true</code>。以下两个 JSX 表达式是等价的：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>MyTextBox autocomplete <span class="token operator">/</span><span class="token operator">&gt;</span>

<span class="token operator">&lt;</span>MyTextBox autocomplete<span class="token operator">=</span><span class="token punctuation">{</span><span class="token boolean">true</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
</code></pre></div><p>通常，我们不建议不传递 value 给 prop，因为这可能与 ES6 对象简写混淆，<code>{foo}</code> 是 <code>{foo: foo}</code> 的简写，而不是 <code>{foo: true}</code>。这样实现只是为了保持和 HTML 中标签属性的行为一致。</p> <h3 id="属性展开"><a href="#属性展开" class="header-anchor">#</a> 属性展开</h3> <p>如果你已经有了一个 props 对象，你可以使用展开运算符 <code>...</code> 来在 JSX 中传递整个 props 对象。以下两个组件是等价的：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">App1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token operator">&lt;</span>Greeting firstName<span class="token operator">=</span><span class="token string">&quot;Ben&quot;</span> lastName<span class="token operator">=</span><span class="token string">&quot;Hector&quot;</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">App2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> props <span class="token operator">=</span> <span class="token punctuation">{</span> firstName<span class="token operator">:</span> <span class="token string">'Ben'</span><span class="token punctuation">,</span> lastName<span class="token operator">:</span> <span class="token string">'Hector'</span> <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token operator">&lt;</span>Greeting <span class="token punctuation">{</span><span class="token operator">...</span>props<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>你还可以选择只保留当前组件需要接收的 props，并使用展开运算符将其他 props 传递下去。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token function-variable function">Button</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">{</span> kind<span class="token punctuation">,</span> <span class="token operator">...</span>other <span class="token punctuation">}</span> <span class="token operator">=</span> props
  <span class="token keyword">const</span> className <span class="token operator">=</span> kind <span class="token operator">===</span> <span class="token string">'primary'</span> <span class="token operator">?</span> <span class="token string">'PrimaryButton'</span> <span class="token operator">:</span> <span class="token string">'SecondaryButton'</span>
  <span class="token keyword">return</span> <span class="token operator">&lt;</span>button className<span class="token operator">=</span><span class="token punctuation">{</span>className<span class="token punctuation">}</span> <span class="token punctuation">{</span><span class="token operator">...</span>other<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> <span class="token function-variable function">App</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token operator">&lt;</span>div<span class="token operator">&gt;</span>
      <span class="token operator">&lt;</span>Button kind<span class="token operator">=</span><span class="token string">&quot;primary&quot;</span> onClick<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'clicked!'</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>
        Hello World<span class="token operator">!</span>
      <span class="token operator">&lt;</span><span class="token operator">/</span>Button<span class="token operator">&gt;</span>
    <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p>在上述例子中，<code>kind</code> 的 prop 会被安全的保留，它将不会被传递给 DOM 中的 <code>&lt;button&gt;</code> 元素。 所有其他的 props 会通过 <code>...other</code> 对象传递，使得这个组件的应用可以非常灵活。你可以看到它传递了一个 <code>onClick</code> 和 <code>children</code> 属性。</p> <p>属性展开在某些情况下很有用，但是也很容易将不必要的 props 传递给不相关的组件，或者将无效的 HTML 属性传递给 DOM。我们建议谨慎的使用该语法。</p> <h2 id="jsx-中的子元素"><a href="#jsx-中的子元素" class="header-anchor">#</a> JSX 中的子元素</h2> <p>包含在开始和结束标签之间的 JSX 表达式内容将作为特定属性 <code>props.children</code> 传递给外层组件。有几种不同的方法来传递子元素：</p> <h3 id="字符串字面量-2"><a href="#字符串字面量-2" class="header-anchor">#</a> 字符串字面量</h3> <p>你可以将字符串放在开始和结束标签之间，此时 <code>props.children</code> 就只是该字符串。这对于很多内置的 HTML 元素很有用。例如：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>MyComponent<span class="token operator">&gt;</span>Hello world<span class="token operator">!</span><span class="token operator">&lt;</span><span class="token operator">/</span>MyComponent<span class="token operator">&gt;</span>
</code></pre></div><p>这是一个合法的 JSX，<code>MyComponent</code> 中的 <code>props.children</code> 是一个简单的未转义字符串 <code>&quot;Hello world!&quot;</code>。因此你可以采用编写 HTML 的方式来编写 JSX。如下所示：</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>This is valid HTML <span class="token entity named-entity" title="&amp;">&amp;amp;</span> JSX at the same time.<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>JSX 会移除行首尾的空格以及空行。与标签相邻的空行均会被删除，文本字符串之间的新行会被压缩为一个空格。因此以下的几种方式都是等价的：</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>Hello World<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
  Hello World
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
  Hello World
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
  Hello World
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h3 id="jsx-子元素"><a href="#jsx-子元素" class="header-anchor">#</a> JSX 子元素</h3> <p>子元素允许由多个 JSX 元素组成。这对于嵌套组件非常有用：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>MyContainer<span class="token operator">&gt;</span>
  <span class="token operator">&lt;</span>MyFirstComponent <span class="token operator">/</span><span class="token operator">&gt;</span>
  <span class="token operator">&lt;</span>MySecondComponent <span class="token operator">/</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>MyContainer<span class="token operator">&gt;</span>
</code></pre></div><p>你可以将不同类型的子元素混合在一起，因此你可以将字符串字面量与 JSX 子元素一起使用。这也是 JSX 类似 HTML 的一种表现，所以如下代码是合法的 JSX 并且也是合法的 HTML：</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
  Here is a list:
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">&gt;</span></span>Item 1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">&gt;</span></span>Item 2<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>React 组件也能够返回存储在数组中的一组元素：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// 不需要用额外的元素包裹列表元素！</span>
<span class="token keyword">return</span> <span class="token punctuation">[</span>
<span class="token comment">// 不要忘记设置 key :)</span>

<span class="token operator">&lt;</span>li key<span class="token operator">=</span><span class="token string">&quot;A&quot;</span><span class="token operator">&gt;</span>First item<span class="token operator">&lt;</span><span class="token operator">/</span>li<span class="token operator">&gt;</span><span class="token punctuation">,</span>
<span class="token operator">&lt;</span>li key<span class="token operator">=</span><span class="token string">&quot;B&quot;</span><span class="token operator">&gt;</span>Second item<span class="token operator">&lt;</span><span class="token operator">/</span>li<span class="token operator">&gt;</span><span class="token punctuation">,</span>
<span class="token operator">&lt;</span>li key<span class="token operator">=</span><span class="token string">&quot;C&quot;</span><span class="token operator">&gt;</span>Third item<span class="token operator">&lt;</span><span class="token operator">/</span>li<span class="token operator">&gt;</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="javascript-表达式作为子元素"><a href="#javascript-表达式作为子元素" class="header-anchor">#</a> JavaScript 表达式作为子元素</h3> <p>JavaScript 表达式可以被包裹在 <code>{}</code> 中作为子元素。例如，以下表达式是等价的：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>MyComponent<span class="token operator">&gt;</span>foo<span class="token operator">&lt;</span><span class="token operator">/</span>MyComponent<span class="token operator">&gt;</span>

<span class="token operator">&lt;</span>MyComponent<span class="token operator">&gt;</span><span class="token punctuation">{</span><span class="token string">'foo'</span><span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>MyComponent<span class="token operator">&gt;</span>
</code></pre></div><p>这对于展示任意长度的列表非常有用。例如，渲染 HTML 列表：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">Item</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token operator">&lt;</span>li<span class="token operator">&gt;</span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>message<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>li<span class="token operator">&gt;</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">TodoList</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> todos <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'finish doc'</span><span class="token punctuation">,</span> <span class="token string">'submit pr'</span><span class="token punctuation">,</span> <span class="token string">'nag dan to review'</span><span class="token punctuation">]</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token operator">&lt;</span>ul<span class="token operator">&gt;</span>
      <span class="token punctuation">{</span>todos<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">message</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
        <span class="token operator">&lt;</span>Item key<span class="token operator">=</span><span class="token punctuation">{</span>message<span class="token punctuation">}</span> message<span class="token operator">=</span><span class="token punctuation">{</span>message<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
      <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span>
    <span class="token operator">&lt;</span><span class="token operator">/</span>ul<span class="token operator">&gt;</span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p>JavaScript 表达式也可以和其他类型的子元素组合。这种做法可以方便地替代模板字符串：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">Hello</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token operator">&lt;</span>div<span class="token operator">&gt;</span>Hello <span class="token punctuation">{</span>props<span class="token punctuation">.</span>addressee<span class="token punctuation">}</span><span class="token operator">!</span><span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="函数作为子元素"><a href="#函数作为子元素" class="header-anchor">#</a> 函数作为子元素</h3> <p>通常，JSX 中的 JavaScript 表达式将会被计算为字符串、React 元素或者是列表。不过，<code>props.children</code> 和其他 prop 一样，它可以传递任意类型的数据，而不仅仅是 React 已知的可渲染类型。例如，如果你有一个自定义组件，你可以把回调函数作为 <code>props.children</code> 进行传递：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 调用子元素回调 numTimes 次，来重复生成组件</span>
<span class="token keyword">function</span> <span class="token function">Repeat</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">let</span> items <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> props<span class="token punctuation">.</span>numTimes<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    items<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>props<span class="token punctuation">.</span><span class="token function">children</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token operator">&lt;</span>div<span class="token operator">&gt;</span><span class="token punctuation">{</span>items<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">ListOfTenThings</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token operator">&lt;</span>Repeat numTimes<span class="token operator">=</span><span class="token punctuation">{</span><span class="token number">10</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>
      <span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token parameter">index</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token operator">&lt;</span>div key<span class="token operator">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span><span class="token operator">&gt;</span>This is item <span class="token punctuation">{</span>index<span class="token punctuation">}</span> <span class="token keyword">in</span> the list<span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span><span class="token punctuation">}</span>
    <span class="token operator">&lt;</span><span class="token operator">/</span>Repeat<span class="token operator">&gt;</span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p>你可以将任何东西作为子元素传递给自定义组件，只要确保在该组件渲染之前能够被转换成 React 理解的对象。这种用法并不常见，但可以用于扩展 JSX。</p> <h3 id="布尔类型、null-以及-undefined-将会忽略"><a href="#布尔类型、null-以及-undefined-将会忽略" class="header-anchor">#</a> 布尔类型、Null 以及 Undefined 将会忽略</h3> <p><code>false</code>, <code>null</code>, <code>undefined</code>, and <code>true</code> 是合法的子元素。但它们并不会被渲染。以下的 JSX 表达式渲染结果相同：</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token punctuation">/&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>{false}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>{null}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>{undefined}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>{true}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>这有助于依据特定条件来渲染其他的 React 元素。例如，在以下 JSX 中，仅当 <code>showHeader</code> 为 <code>true</code> 时，才会渲染 <code>&lt;Header /&gt;</code> 组件：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>div<span class="token operator">&gt;</span>
  <span class="token punctuation">{</span>showHeader <span class="token operator">&amp;&amp;</span> <span class="token operator">&lt;</span>Header <span class="token operator">/</span><span class="token operator">&gt;</span><span class="token punctuation">}</span>
  <span class="token operator">&lt;</span>Content <span class="token operator">/</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
</code></pre></div><p>值得注意的是有一些 “falsy” 值，如数字 <code>0</code>，仍然会被 React 渲染。例如，以下代码并不会像你预期那样工作，因为当 <code>props.messages</code> 是空数组时，将会渲染为数字 <code>0</code>：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>div<span class="token operator">&gt;</span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>messages<span class="token punctuation">.</span>length <span class="token operator">&amp;&amp;</span> <span class="token operator">&lt;</span>MessageList messages<span class="token operator">=</span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>messages<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">&gt;</span><span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
</code></pre></div><p>要解决这个问题，确保 <code>&amp;&amp;</code> 之前的表达式总是布尔值：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>div<span class="token operator">&gt;</span>
  <span class="token punctuation">{</span>props<span class="token punctuation">.</span>messages<span class="token punctuation">.</span>length <span class="token operator">&gt;</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">&lt;</span>MessageList messages<span class="token operator">=</span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>messages<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">&gt;</span><span class="token punctuation">}</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
</code></pre></div><p>反之，如果你想渲染 <code>false</code>、<code>true</code>、<code>null</code>、<code>undefined</code> 等值，你需要先将它们转换为字符串：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">;</span><span class="token operator">&lt;</span>div<span class="token operator">&gt;</span>My JavaScript variable is <span class="token punctuation">{</span><span class="token function">String</span><span class="token punctuation">(</span>myVariable<span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">.</span><span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
<span class="token keyword">const</span> nullVar <span class="token operator">=</span> <span class="token keyword">null</span>
nullVar<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// TypeError: nullVar is null</span>
<span class="token function">String</span><span class="token punctuation">(</span>nullVar<span class="token punctuation">)</span> <span class="token comment">// &quot;null&quot;</span>

<span class="token keyword">const</span> undefinedVar <span class="token operator">=</span> <span class="token keyword">undefined</span>
undefinedVar<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// TypeError: undefinedVar is undefined</span>
<span class="token function">String</span><span class="token punctuation">(</span>undefinedVar<span class="token punctuation">)</span> <span class="token comment">// &quot;undefined&quot;</span>
</code></pre></div><h2 id="react-组件基础"><a href="#react-组件基础" class="header-anchor">#</a> React 组件基础</h2> <p><code>组件概念:</code></p> <p><strong>在 React 当中元素和组件是两个不同的概念，组件是构建在元素的基础之上的。React 官方对组件的定义，是指在 UI 界面中，可以被独立划分的、可复用的、独立的模块。</strong></p> <p><img src="http://zscnb.gitee.io/upload/static/img/image.png" draggable="false" alt="image-20201026174611477"></p> <h3 id="函数组件"><a href="#函数组件" class="header-anchor">#</a> 函数组件</h3> <p><code>目标任务</code>: 能够独立使用函数完成 react 组件的创建和渲染</p> <p><code>概念</code></p> <p><strong>使用 JS 的函数（或箭头函数）创建的组件，就叫做函数组件</strong></p> <p><strong>函数组件定义与渲染</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 定义函数组件</span>
<span class="token keyword">function</span> <span class="token function">HelloFn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">这是我的第一个函数组件!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token punctuation">}</span>

<span class="token comment">// 定义函数组件</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token comment">/* 渲染函数组件 */</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">HelloFn</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">HelloFn</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">HelloFn</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><p><strong>约定说明</strong></p> <ol><li>函数组件的名称必须<strong>首字母大写</strong>，react 内部会根据这个来判断是组件还是普通的 HTML 标签</li> <li>函数组件必须有<strong>返回值</strong>，表示该组件的 UI 结构；如果不需要渲染任何内容，则返回 <strong>null</strong></li> <li>组件就像 HTML 标签一样可以被渲染到页面中。组件表示的是一段结构内容，对于函数组件来说，渲染的内容是函数的返回值就是对应的内容</li> <li>使用函数名称作为组件标签名称，可以成对出现也可以自闭合</li></ol> <h3 id="类组件"><a href="#类组件" class="header-anchor">#</a> 类组件</h3> <p><code>目标任务</code>: 能够独立完成类组件的创建和渲染</p> <p><strong>使用 ES6 的 class 创建的组件，叫做类（class）组件</strong></p> <p><strong>类组件定义与渲染</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 引入React</span>
<span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token comment">// 定义类组件</span>
<span class="token keyword">class</span> <span class="token class-name">HelloC</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">这是我的第一个类组件!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token comment">/* 渲染类组件 */</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">HelloC</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">HelloC</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">HelloC</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><p><strong>约定说明</strong></p> <ol><li>类名称也必须以<strong>大写字母</strong>开头</li> <li>类组件应该<strong>继承</strong> React.Component 父类，从而使用父类中提供的方法或属性</li> <li>类组件必须提供 render 方法 render 方法必须有返回值，表示该组件的 UI 结构</li></ol> <h2 id="函数组件的事件绑定"><a href="#函数组件的事件绑定" class="header-anchor">#</a> 函数组件的事件绑定</h2> <p><code>目标任务</code>: 能够独立绑定任何事件并能获取到事件对象 e</p> <ol><li><p><strong>如何绑定事件</strong></p> <p><strong>语法</strong></p> <ul><li>on + 事件名称 = { 事件处理程序 } ，比如：&lt;div onClick={ onClick }&gt;</li> <li>((注意点))</li> <li>react 事件采用驼峰命名法，比如：onMouseEnter、onFocus</li></ul></li></ol> <p><strong>样例</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 函数组件</span>
<span class="token keyword">function</span> <span class="token function">HelloFn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 定义事件回调函数</span>
  <span class="token keyword">const</span> <span class="token function-variable function">clickHandler</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'事件被触发了'</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token comment">// 绑定事件</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>clickHandler<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">click me!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><ol start="2"><li><p><strong>获取事件对象</strong></p> <blockquote><p>获取事件对象 e 只需要在 事件的回调函数中 补充一个形参 e 即可拿到</p></blockquote></li> <li><p><strong>传递额外参数</strong>
解决思路:</p> <ul><li>改造事件绑定为箭头函数</li> <li>在箭头函数中完成参数的传递</li></ul></li></ol> <div class="language-jsx extra-class"><pre class="language-jsx"><code>
<span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">&quot;react&quot;</span>

<span class="token comment">// 如何获取额外的参数？</span>
<span class="token comment">// onClick={ onDel } -&gt; onClick={ () =&gt; onDel(id) }</span>
<span class="token comment">// 注意: 一定不要在模板中写出函数调用的代码 onClick = { onDel(id) }  bad!!!!!!</span>

<span class="token keyword">const</span> <span class="token function-variable function">TestComponent</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> list <span class="token operator">=</span> <span class="token punctuation">[</span>
    <span class="token punctuation">{</span>
      id<span class="token operator">:</span> <span class="token number">1001</span><span class="token punctuation">,</span>
      name<span class="token operator">:</span> <span class="token string">'react'</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">{</span>
      id<span class="token operator">:</span> <span class="token number">1002</span><span class="token punctuation">,</span>
      name<span class="token operator">:</span> <span class="token string">'vue'</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">]</span>
  <span class="token keyword">const</span> <span class="token function-variable function">onDel</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">e<span class="token punctuation">,</span> id</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">,</span> id<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span>list<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token parameter">item</span> <span class="token operator">=&gt;</span>（
           <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>item<span class="token punctuation">.</span>id<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
                </span><span class="token punctuation">{</span>item<span class="token punctuation">.</span>name<span class="token punctuation">}</span><span class="token plain-text">
                </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">onDel</span><span class="token punctuation">(</span>e<span class="token punctuation">,</span> item<span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">x</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
           </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
        <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">App</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TestComponent</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>


<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h2 id="类组件的事件绑定"><a href="#类组件的事件绑定" class="header-anchor">#</a> <strong>类组件的事件绑定</strong></h2> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 类组件中的事件绑定</span>
<span class="token comment">// 整体的套路都是一致的 和函数组件没有太多不同</span>
<span class="token comment">// 唯一需要注意的 因为处于class 类环境下 所以定义事件回调函数 以及 绑定它写法上有不同</span>
<span class="token comment">// 定义的时候: class Fields语法</span>
<span class="token comment">// 使用的时候: 需要借助this关键词获取</span>

<span class="token comment">// 注意事项: 之所以要采取class Fields写法是为了保证this的指向正确 永远指向当前的组件实例</span>

<span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">class</span> <span class="token class-name">CComponent</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token comment">// class Fields</span>
  <span class="token function-variable function">clickHandler</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">e<span class="token punctuation">,</span> num</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">// 这里的this指向的是正确的当前的组件实例对象</span>
    <span class="token comment">// 可以非常方便的通过this关键词拿到组件实例身上的其他属性或者方法</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>

  <span class="token function">clickHandler1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 这里的this 不指向当前的组件实例对象  undefined 存在this丢失问题</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>

  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">clickHandler</span><span class="token punctuation">(</span>e<span class="token punctuation">,</span> <span class="token string">'123'</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">click me</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>clickHandler1<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">click me</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">CComponent</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h2 id="组件状态"><a href="#组件状态" class="header-anchor">#</a> 组件状态</h2> <p><code>目标任务</code>: 能够为组件添加状态和修改状态的值</p> <p><strong>一个前提：在 React hook 出来之前，函数式组件是没有自己的状态的，所以我们统一通过类组件来讲解</strong></p> <p><img src="http://zscnb.gitee.io/upload/static/img/state-update.png" draggable="false" alt="image-20201026174611477"></p> <h3 id="_1-初始化状态"><a href="#_1-初始化状态" class="header-anchor">#</a> 1. 初始化状态</h3> <ul><li>通过 class 的实例属性 state 来初始化</li> <li>state 的值是一个对象结构，表示一个组件可以有多个数据状态</li></ul> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">class</span> <span class="token class-name">Counter</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token comment">// 初始化状态</span>
  state <span class="token operator">=</span> <span class="token punctuation">{</span>
    count<span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">计数器</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="_2-读取状态"><a href="#_2-读取状态" class="header-anchor">#</a> 2. 读取状态</h3> <p>● 通过 this.state 来获取状态</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">class</span> <span class="token class-name">Counter</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token comment">// 初始化状态</span>
  state <span class="token operator">=</span> <span class="token punctuation">{</span>
    count<span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 读取状态</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">计数器</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="_3-修改状态"><a href="#_3-修改状态" class="header-anchor">#</a> 3. 修改状态</h3> <ul><li><p>语法
<code>this.setState({ 要修改的部分数据 })</code></p></li> <li><p>setState 方法作用</p> <p>a. 修改 state 中的数据状态</p> <p>b. 更新 UI</p></li> <li><p>思想</p></li></ul> <p>数据驱动视图，也就是只要修改数据状态，那么页面就会自动刷新，无需手动操作 dom</p> <ul><li>注意事项</li></ul> <p>不要直接修改 state 中的值，必须通过 setState 方法进行修改</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">class</span> <span class="token class-name">Counter</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token comment">// 定义数据</span>
  state <span class="token operator">=</span> <span class="token punctuation">{</span>
    count<span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 定义修改数据的方法</span>
  <span class="token function-variable function">setCount</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      count<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 使用数据 并绑定事件</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>setCount<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="this-问题说明"><a href="#this-问题说明" class="header-anchor">#</a> this 问题说明</h2> <p>空缺</p> <h2 id="react-的状态不可变"><a href="#react-的状态不可变" class="header-anchor">#</a> React 的状态不可变</h2> <p><code>目标任务</code>: 能够理解不可变的意义并且知道在实际开发中如何修改状态</p> <p><strong>重点</strong> <strong>概念：不要直接修改状态的值，而是基于当前状态创建新的状态值</strong></p> <h3 id="_1-错误的直接修改"><a href="#_1-错误的直接修改" class="header-anchor">#</a> 1. 错误的直接修改</h3> <div class="language-jsx extra-class"><pre class="language-jsx"><code>state <span class="token operator">=</span> <span class="token punctuation">{</span>
  count<span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
  list<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
  person<span class="token operator">:</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">'jack'</span><span class="token punctuation">,</span>
    age<span class="token operator">:</span> <span class="token number">18</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token comment">// 直接修改简单类型Number</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count<span class="token operator">++</span>
<span class="token operator">++</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count
<span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count <span class="token operator">+=</span> <span class="token number">1</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count <span class="token operator">=</span> <span class="token number">1</span>

<span class="token comment">// 直接修改数组</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token number">123</span><span class="token punctuation">)</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">spice</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>

<span class="token comment">// 直接修改对象</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>person<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">'rose'</span>
</code></pre></div><h3 id="_2-基于当前状态创建新值-推荐修改"><a href="#_2-基于当前状态创建新值-推荐修改" class="header-anchor">#</a> 2. 基于当前状态创建新值(推荐修改)</h3> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    count<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count <span class="token operator">+</span> <span class="token number">1</span>
    list<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token operator">...</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>list<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
    person<span class="token operator">:</span> <span class="token punctuation">{</span>
       <span class="token operator">...</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>person<span class="token punctuation">,</span>
       <span class="token comment">// 覆盖原来的属性 就可以达到修改对象中属性的目的</span>
       name<span class="token operator">:</span> <span class="token string">'rose'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><h2 id="表单处理"><a href="#表单处理" class="header-anchor">#</a> 表单处理</h2> <p><code>目标任务</code>: 能够使用受控组件的方式获取文本框的值</p> <p>使用 React 处理表单元素，一般有俩种方式：</p> <ol><li>受控组件 （推荐使用）</li> <li>非受控组件 （了解）</li></ol> <h3 id="_1-受控表单组件"><a href="#_1-受控表单组件" class="header-anchor">#</a> 1. 受控表单组件</h3> <p><strong>什么是受控组件？ input 框自己的状态被 React 组件状态控制</strong></p> <p>React 组件的状态的地方是在 state 中，input 表单元素也有自己的状态是在 value 中，React 将 state 与表单元素的值（value）绑定到一起，由 state 的值来控制表单元素的值，从而保证单一数据源特性</p> <p><code>实现步骤</code></p> <p>以获取文本框的值为例，受控组件的使用步骤如下：</p> <ol><li>在组件的 state 中声明一个组件的状态数据</li> <li>将状态数据设置为 input 标签元素的 value 属性的值</li> <li>为 input 添加 change 事件，在事件处理程序中，通过事件对象 e 获取到当前文本框的值（即用户当前输入的值）</li> <li>调用 setState 方法，将文本框的值作为 state 状态的最新值</li></ol> <p>代码落地</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token keyword">class</span> <span class="token class-name">InputComponent</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token comment">// 声明组件状态</span>
  state <span class="token operator">=</span> <span class="token punctuation">{</span>
    message<span class="token operator">:</span> <span class="token string">'this is message'</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 声明事件回调函数</span>
  <span class="token function-variable function">changeHandler</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> message<span class="token operator">:</span> e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>value <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token comment">/* 绑定value 绑定事件*/</span><span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">value</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>message<span class="token punctuation">}</span></span> <span class="token attr-name">onChange</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>changeHandler<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">InputComponent</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h3 id="_2-非受控表单组件"><a href="#_2-非受控表单组件" class="header-anchor">#</a> 2. 非受控表单组件</h3> <p>什么是非受控组件？</p> <p><strong>非受控组件就是通过手动操作 dom 的方式获取文本框的值，文本框的状态不受 react 组件的 state 中的状态控制，直接通过原生 dom 获取输入框的值</strong></p> <p><code>实现步骤</code></p> <ol><li>导入<code>createRef</code> 函数</li> <li>调用 createRef 函数，创建一个<code>ref对象</code>，存储到名为<code>msgRef</code>的实例属性中</li> <li>为 input 添加 ref 属性，值为<code>msgRef</code></li> <li>在按钮的事件处理程序中，通过<code>msgRef.current</code>即可拿到 input 对应的 dom 元素，而其中<code>msgRef.current.value</code>拿到的就是文本框的值</li></ol> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> createRef <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token keyword">class</span> <span class="token class-name">InputComponent</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token comment">// 使用createRef产生一个存放dom的对象容器</span>
  msgRef <span class="token operator">=</span> <span class="token function">createRef</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

  <span class="token function-variable function">changeHandler</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>msgRef<span class="token punctuation">.</span>current<span class="token punctuation">.</span>value<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>

  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token comment">/* ref绑定 获取真实dom */</span><span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">ref</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>msgRef<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>changeHandler<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">click</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">InputComponent</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h2 id="react-组件通信"><a href="#react-组件通信" class="header-anchor">#</a> React 组件通信</h2> <h3 id="组件通信的意义"><a href="#组件通信的意义" class="header-anchor">#</a> 组件通信的意义</h3> <p><code>目标任务</code>: 了解为什么需要组件通信</p> <p><strong>组件是独立且封闭的单元，默认情况下组件只能使用自己的数据（state）</strong> <strong>组件化开发的过程中，完整的功能会拆分多个组件，在这个过程中不可避免的需要互相传递一些数据</strong> <strong>为了能让各组件之间可以进行互相沟通，数据传递，这个过程就是组件通信</strong></p> <ol><li>父子关系 - 最重要的</li> <li>兄弟关系 - 自定义事件模式产生技术方法 eventBus / 通过共同的父组件通信</li> <li>其它关系 - mobx / redux / zustand</li></ol> <h3 id="父传子实现"><a href="#父传子实现" class="header-anchor">#</a> 父传子实现</h3> <p><code>目标任务</code>: 实现父子通信中的父传子，把父组件中的数据传给子组件</p> <p>实现步骤</p> <ol><li>父组件提供要传递的数据 - state</li> <li>给子组件标签添加属性值为 state 中的数据</li> <li>子组件中通过 props 接收父组件中传过来的数据</li></ol> <ul><li>a. 类组件使用 this.props 获取 props 对象</li> <li>b. 函数式组件直接通过参数获取 props 对象</li></ul> <p><img src="http://zscnb.gitee.io/upload/static/img/props-1.png" draggable="false" alt="image-20201026174611477"></p> <p><strong>代码实现</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token comment">// 函数式子组件</span>
<span class="token keyword">function</span> <span class="token function">FSon</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      子组件1
      </span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>msg<span class="token punctuation">}</span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token comment">// 类子组件</span>
<span class="token keyword">class</span> <span class="token class-name">CSon</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        子组件2
        </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>msg<span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// 父组件</span>
<span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  state <span class="token operator">=</span> <span class="token punctuation">{</span>
    message<span class="token operator">:</span> <span class="token string">'this is message'</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">父组件</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">FSon</span></span> <span class="token attr-name">msg</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>message<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">CSon</span></span> <span class="token attr-name">msg</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>message<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h3 id="props-说明"><a href="#props-说明" class="header-anchor">#</a> props 说明</h3> <p><code>目标任务</code>: 知道 props 传递时的一些注意事项</p> <p><strong>1. props 是只读对象（readonly）</strong></p> <p>根据单项数据流的要求，子组件只能读取 props 中的数据，不能进行修改</p> <p><strong>2. props 可以传递任意数据</strong></p> <p><strong>数字、字符串、布尔值、数组、对象、<code>函数、JSX</code></strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  state <span class="token operator">=</span> <span class="token punctuation">{</span>
    message<span class="token operator">:</span> <span class="token string">'this is message'</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">父组件</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">FSon</span></span>
          <span class="token attr-name">msg</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>message<span class="token punctuation">}</span></span>
          <span class="token attr-name">age</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token number">20</span><span class="token punctuation">}</span></span>
          <span class="token attr-name">isMan</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token boolean">true</span><span class="token punctuation">}</span></span>
          <span class="token attr-name">cb</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
            console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
          <span class="token punctuation">}</span><span class="token punctuation">}</span></span>
          <span class="token attr-name">child</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">this is child</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">}</span></span>
        <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">CSon</span></span> <span class="token attr-name">msg</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>message<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p><img src="http://zscnb.gitee.io/upload/static/img/props-2.png" draggable="false" alt="image-20201026174611477"></p> <h3 id="子传父实现"><a href="#子传父实现" class="header-anchor">#</a> 子传父实现</h3> <p><code>目标任务</code>: 实现父子通信中的子传父</p> <p><strong>口诀： 父组件给子组件传递回调函数，子组件调用</strong></p> <p><strong>实现步骤</strong></p> <ol><li>父组件提供一个回调函数 - 用于接收数据</li> <li>将函数作为属性的值，传给子组件</li> <li>子组件通过 props 调用 回调函数</li> <li>将子组件中的数据作为参数传递给回调函数</li></ol> <p><img src="http://zscnb.gitee.io/upload/static/img/props-4.png" draggable="false" alt="image-20201026174611477"></p> <p><strong>代码实现</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token comment">// 子组件</span>
<span class="token keyword">function</span> <span class="token function">Son</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">function</span> <span class="token function">handleClick</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 调用父组件传递过来的回调函数 并注入参数</span>
    props<span class="token punctuation">.</span><span class="token function">changeMsg</span><span class="token punctuation">(</span><span class="token string">'this is newMessage'</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>msg<span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>handleClick<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">change</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  state <span class="token operator">=</span> <span class="token punctuation">{</span>
    message<span class="token operator">:</span> <span class="token string">'this is message'</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 提供回调函数</span>
  <span class="token function-variable function">changeMessage</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">newMsg</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'子组件传过来的数据:'</span><span class="token punctuation">,</span> newMsg<span class="token punctuation">)</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      message<span class="token operator">:</span> newMsg<span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">父组件</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        &lt;Son
          msg=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>message<span class="token punctuation">}</span><span class="token plain-text">
          // 传递给子组件
          changeMsg=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>changeMessage<span class="token punctuation">}</span><span class="token plain-text">
        /&gt;
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h3 id="兄弟组件通信"><a href="#兄弟组件通信" class="header-anchor">#</a> 兄弟组件通信</h3> <p><code>目标任务</code>: 实现兄弟组件之间的通信</p> <p><strong>核心思路： 通过状态提升机制，利用共同的父组件实现兄弟通信</strong></p> <p><img src="http://zscnb.gitee.io/upload/static/img/props-5.png" draggable="false" alt="image-20201026174611477"></p> <p><strong>实现步骤</strong></p> <ol><li>将共享状态提升到最近的公共父组件中，由公共父组件管理这个状态
○ 提供共享状态
○ 提供操作共享状态的方法</li> <li>要接收数据状态的子组件通过 props 接收数据</li> <li>要传递数据状态的子组件通过 props 接收方法，调用方法传递数据</li></ol> <p><strong>代码实现</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token comment">// 子组件A</span>
<span class="token keyword">function</span> <span class="token function">SonA</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      SonA
      </span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>msg<span class="token punctuation">}</span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// 子组件B</span>
<span class="token keyword">function</span> <span class="token function">SonB</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      SonB
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> props<span class="token punctuation">.</span><span class="token function">changeMsg</span><span class="token punctuation">(</span><span class="token string">'new message'</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">changeMsg</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token comment">// 父组件</span>
<span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token comment">// 父组件提供状态数据</span>
  state <span class="token operator">=</span> <span class="token punctuation">{</span>
    message<span class="token operator">:</span> <span class="token string">'this is message'</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 父组件提供修改数据的方法</span>
  <span class="token function-variable function">changeMsg</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">newMsg</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      message<span class="token operator">:</span> newMsg<span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>

  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token comment">/* 接收数据的组件 */</span><span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">SonA</span></span> <span class="token attr-name">msg</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>message<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token comment">/* 修改数据的组件 */</span><span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">SonB</span></span> <span class="token attr-name">changeMsg</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>changeMsg<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h3 id="跨组件通信-context"><a href="#跨组件通信-context" class="header-anchor">#</a> 跨组件通信 Context</h3> <p><code>目标任务</code>: 了解 Context 机制解决的问题和使用步骤</p> <p><img src="http://zscnb.gitee.io/upload/static/img/context.png" draggable="false" alt="image-20201026174611477"></p> <p>上图是一个 react 形成的嵌套组件树，如果我们想从 App 组件向任意一个下层组件传递数据，该怎么办呢？目前我们能采取的方式就是一层一层的 props 往下传，显然很繁琐
那么，Context 提供了一个无需为每层组件手动添加 props，就能在组件树间进行数据传递的方法</p> <p><strong>实现步骤</strong></p> <p>1- 创建<code>Context</code>对象 导出 <code>Provider</code>和 <code>Consumer</code>对象</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">const</span> <span class="token punctuation">{</span> Provider<span class="token punctuation">,</span> Consumer <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">createContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre></div><p>2- 使用 Provider 包裹上层组件提供数据</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Provider</span></span> <span class="token attr-name">value</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>message<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span><span class="token comment">/* 根组件 */</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Provider</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>3- 需要用到数据的组件使用 Consumer 包裹获取数据</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Consumer</span></span> <span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token punctuation">{</span><span class="token parameter">value</span> <span class="token operator">=&gt;</span> <span class="token comment">/* 基于 context 值进行渲染*/</span><span class="token punctuation">}</span><span class="token plain-text">
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Consumer</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><strong>代码实现</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> createContext <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token comment">// 1. 创建Context对象</span>
<span class="token keyword">const</span> <span class="token punctuation">{</span> Provider<span class="token punctuation">,</span> Consumer <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">createContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token comment">// 3. 消费数据</span>
<span class="token keyword">function</span> <span class="token function">ComC</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Consumer</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>value<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Consumer</span></span><span class="token punctuation">&gt;</span></span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">ComA</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ComC</span></span> <span class="token punctuation">/&gt;</span></span>
<span class="token punctuation">}</span>

<span class="token comment">// 2. 提供数据</span>
<span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  state <span class="token operator">=</span> <span class="token punctuation">{</span>
    message<span class="token operator">:</span> <span class="token string">'this is message'</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Provider</span></span> <span class="token attr-name">value</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>message<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>app<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
          </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ComA</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Provider</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h3 id="阶段小练习"><a href="#阶段小练习" class="header-anchor">#</a> 阶段小练习</h3> <p><strong>要求：App 为父组件用来提供列表数据 ，ListItem 为子组件用来渲染列表数据</strong></p> <p><img src="http://zscnb.gitee.io/upload/static/img/props-3.png" draggable="false" alt="image-20201026174611477"></p> <div class="language-sh extra-class"><pre class="language-sh"><code>
// 列表数据
<span class="token punctuation">[</span>
  <span class="token punctuation">{</span> id: <span class="token number">1</span>, name: <span class="token string">'超级好吃的棒棒糖'</span>, price: <span class="token number">18.8</span>, info: <span class="token string">'开业大酬宾，全场8折'</span> <span class="token punctuation">}</span>,
  <span class="token punctuation">{</span> id: <span class="token number">2</span>, name: <span class="token string">'超级好吃的大鸡腿'</span>, price: <span class="token number">34.2</span>, info: <span class="token string">'开业大酬宾，全场8折'</span> <span class="token punctuation">}</span>,
  <span class="token punctuation">{</span> id: <span class="token number">3</span>, name: <span class="token string">'超级无敌的冰激凌'</span>, price: <span class="token number">14.2</span>, info: <span class="token string">'开业大酬宾，全场8折'</span> <span class="token punctuation">}</span>
<span class="token punctuation">]</span>
</code></pre></div><p><strong>完整代码</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token comment">// 子组件</span>
<span class="token keyword">function</span> <span class="token function">ListItem</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">{</span> name<span class="token punctuation">,</span> price<span class="token punctuation">,</span> info<span class="token punctuation">,</span> id<span class="token punctuation">,</span> delHandler <span class="token punctuation">}</span> <span class="token operator">=</span> props
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>name<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>price<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>info<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">delHandler</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">删除</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token comment">// 父组件</span>
<span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  state <span class="token operator">=</span> <span class="token punctuation">{</span>
    list<span class="token operator">:</span> <span class="token punctuation">[</span>
      <span class="token punctuation">{</span>
        id<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
        name<span class="token operator">:</span> <span class="token string">'超级好吃的棒棒糖'</span><span class="token punctuation">,</span>
        price<span class="token operator">:</span> <span class="token number">18.8</span><span class="token punctuation">,</span>
        info<span class="token operator">:</span> <span class="token string">'开业大酬宾，全场8折'</span><span class="token punctuation">,</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
      <span class="token punctuation">{</span>
        id<span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
        name<span class="token operator">:</span> <span class="token string">'超级好吃的大鸡腿'</span><span class="token punctuation">,</span>
        price<span class="token operator">:</span> <span class="token number">34.2</span><span class="token punctuation">,</span>
        info<span class="token operator">:</span> <span class="token string">'开业大酬宾，全场8折'</span><span class="token punctuation">,</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
      <span class="token punctuation">{</span>
        id<span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span>
        name<span class="token operator">:</span> <span class="token string">'超级无敌的冰激凌'</span><span class="token punctuation">,</span>
        price<span class="token operator">:</span> <span class="token number">14.2</span><span class="token punctuation">,</span>
        info<span class="token operator">:</span> <span class="token string">'开业大酬宾，全场8折'</span><span class="token punctuation">,</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>

  <span class="token function-variable function">delHandler</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      <span class="token comment">// 删除某个元素 filter</span>
      list<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> item<span class="token punctuation">.</span>id <span class="token operator">!==</span> id<span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>

  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token comment">// 列表展示 map</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ListItem</span></span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>item<span class="token punctuation">.</span>id<span class="token punctuation">}</span></span> <span class="token spread"><span class="token punctuation">{</span><span class="token punctuation">...</span><span class="token attr-value">item</span><span class="token punctuation">}</span></span> <span class="token attr-name">delHandler</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>delHandler<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h2 id="react-组件进阶"><a href="#react-组件进阶" class="header-anchor">#</a> React 组件进阶</h2> <h3 id="children-属性"><a href="#children-属性" class="header-anchor">#</a> children 属性</h3> <p><code>目标任务</code>: 掌握 props 中 children 属性的用法</p> <p><strong>children 属性是什么</strong></p> <p>表示该组件的子节点，只要组件内部有子节点，props 中就有该属性</p> <p><strong>children 可以是什么</strong></p> <ol><li>普通文本</li> <li>普通标签元素</li> <li>函数 / 对象</li> <li>JSX</li></ol> <p><strong>目的：高阶组件</strong></p> <h3 id="props-校验-场景和使用"><a href="#props-校验-场景和使用" class="header-anchor">#</a> props 校验-场景和使用</h3> <p><code>目标任务</code>: 掌握组件 props 的校验写法，增加组件的健壮性</p> <blockquote><p>对于组件来说，props 是由外部传入的，我们其实无法保证组件使用者传入了什么格式的数据，如果传入的数据格式不对，就有可能会导致 组件内部错误，有一个点很关键 - 组件的使用者可能报错了也不知道为什么，看下面的例子</p></blockquote> <p><img src="http://zscnb.gitee.io/upload/static/img/props-rule.png" draggable="false" alt="image-20201026174611477"></p> <p><strong>面对这样的问题，如何解决？ props 校验</strong></p> <p><strong>实现步骤</strong></p> <ol><li>安装属性校验包：<code>yarn add prop-types</code></li> <li>导入<code>prop-types</code>包</li> <li>使用 <code>组件名.propTypes = {}</code>给组件添加校验规则</li></ol> <p><strong>核心代码</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> PropTypes <span class="token keyword">from</span> <span class="token string">'prop-types'</span>

<span class="token keyword">const</span> <span class="token function-variable function">List</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> arr <span class="token operator">=</span> props<span class="token punctuation">.</span>colors
  <span class="token keyword">const</span> lis <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>item<span class="token punctuation">.</span>name<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>lis<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span>
<span class="token punctuation">}</span>

List<span class="token punctuation">.</span>propTypes <span class="token operator">=</span> <span class="token punctuation">{</span>
  colors<span class="token operator">:</span> PropTypes<span class="token punctuation">.</span>array<span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="props-校验-规则说明"><a href="#props-校验-规则说明" class="header-anchor">#</a> props 校验-规则说明</h3> <p><code>目标任务</code>: 掌握 props 常见的规则</p> <p>四种常见结构</p> <ol><li>常见类型：<strong>array、bool、func、number、object、string</strong></li> <li>React 元素类型：<strong>element</strong></li> <li>必填项：<strong>isRequired</strong></li> <li>特定的结构对象：<strong>shape({})</strong></li></ol> <p><strong>核心代码</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 常见类型</span>
optionalFunc<span class="token operator">:</span> PropTypes<span class="token punctuation">.</span>func<span class="token punctuation">,</span>
<span class="token comment">// 必填 只需要在类型后面串联一个isRequired</span>
requiredFunc<span class="token operator">:</span> PropTypes<span class="token punctuation">.</span>func<span class="token punctuation">.</span>isRequired<span class="token punctuation">,</span>
<span class="token comment">// 特定结构的对象</span>
optionalObjectWithShape<span class="token operator">:</span> PropTypes<span class="token punctuation">.</span><span class="token function">shape</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
	color<span class="token operator">:</span> PropTypes<span class="token punctuation">.</span>string<span class="token punctuation">,</span>
	fontSize<span class="token operator">:</span> PropTypes<span class="token punctuation">.</span>number
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p><a href="https://reactjs.org/docs/typechecking-with-proptypes.html" target="_blank" rel="noopener noreferrer">官网文档更多阅读<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <h3 id="props-校验-默认值"><a href="#props-校验-默认值" class="header-anchor">#</a> props 校验-默认值</h3> <p><code>目标任务</code>: 掌握如何给组件的 props 提供默认值</p> <p><strong>1. 函数组件</strong></p> <p><strong>通过 defaultProps 可以给组件的 props 设置默认值，在未传入 props 的时候生效</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">function</span> <span class="token function">List</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">此处展示props的默认值：</span><span class="token punctuation">{</span>pageSize<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token punctuation">}</span>

List<span class="token punctuation">.</span>defaultProps <span class="token operator">=</span> <span class="token punctuation">{</span>
  pageSize<span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><p><strong>直接使用函数参数默认值（推荐）</strong></p> <p>注意：函数组件，新版的 react 已经不再使用 defaultProps 来添加默认值，而是<code>函数参数默认值</code>来实现</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">function</span> <span class="token function">List</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> pageSize <span class="token operator">=</span> <span class="token number">10</span> <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">此处展示props的默认值：</span><span class="token punctuation">{</span>pageSize<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token punctuation">}</span>

<span class="token comment">// 不传入pageSize属性</span>
<span class="token punctuation">;</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">List</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre></div><p><strong>2. 类组件</strong></p> <p><strong>使用 defaultProps 设置默认值</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">class</span> <span class="token class-name">List</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>

  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">此处展示props的默认值：</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>pageSize<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
List<span class="token punctuation">.</span>defaultProps <span class="token operator">=</span> <span class="token punctuation">{</span>
  pageSize<span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">List</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre></div><p><strong>使用类静态属性声明默认值，static defaultProps = {}</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">class</span> <span class="token class-name">List</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token keyword">static</span> defaultProps <span class="token operator">=</span> <span class="token punctuation">{</span>
    pageSize<span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">此处展示props的默认值：</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>pageSize<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">;</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">List</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre></div><h2 id="生命周期"><a href="#生命周期" class="header-anchor">#</a> 生命周期</h2> <p><strong>概述</strong></p> <p><code>目标任务</code>: 能够说出组件生命周期一共几个阶段</p> <blockquote><p>组件的生命周期是指组件从被创建到挂载到页面中运行起来，再到组件不用时卸载的过程，注意，只有类组件才有生命周期（类组件 实例化 函数组件 不需要实例化）</p></blockquote> <p><img src="http://zscnb.gitee.io/upload/static/img/life.png" draggable="false" alt="image-20201026174611477"></p> <p><a href="http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/" target="_blank" rel="noopener noreferrer">生命周期<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <h3 id="生命周期-挂载阶段"><a href="#生命周期-挂载阶段" class="header-anchor">#</a> 生命周期 - 挂载阶段</h3> <p><code>目标任务</code>: 能够说出在组件挂载阶段执行的钩子函数和执行时机</p> <p><img src="http://zscnb.gitee.io/upload/static/img/life1.png" draggable="false" alt="image-20201026174611477"></p> <table><thead><tr><th>钩子函数</th> <th>触发时机</th> <th>作用</th></tr></thead> <tbody><tr><td>constructor</td> <td>创建组件时，最先执行，初始化的时候只执行一次</td> <td>1. 初始化 state 2. 创建 Ref 3. 使用 bind 解决 this 指向问题等</td></tr> <tr><td>render</td> <td>每次组件渲染都会触发</td> <td>渲染 UI（注意： 不能在里面调用 setState() ）</td></tr> <tr><td>componentDidMount</td> <td>组件挂载（完成 DOM 渲染）后执行，初始化的时候执行一次</td> <td>1. 发送网络请求 2.DOM 操作</td></tr></tbody></table> <h3 id="生命周期-更新阶段"><a href="#生命周期-更新阶段" class="header-anchor">#</a> 生命周期 - 更新阶段</h3> <p><code>目标任务</code>: 能够说出组件的更新阶段的钩子函数以及执行时机</p> <p><img src="http://zscnb.gitee.io/upload/static/img/life2.png" draggable="false" alt="image-20201026174611477"></p> <table><thead><tr><th>钩子函数</th> <th>触发时机</th> <th>作用</th></tr></thead> <tbody><tr><td>render</td> <td>每次组件渲染都会触发</td> <td>渲染 UI（与 挂载阶段 是同一个 render）</td></tr> <tr><td>componentDidUpdate</td> <td>组件更新后（DOM 渲染完毕）</td> <td>DOM 操作，可以获取到更新后的 DOM 内容，不要直接调用 setState</td></tr></tbody></table> <h3 id="生命周期-卸载阶段"><a href="#生命周期-卸载阶段" class="header-anchor">#</a> 生命周期 - 卸载阶段</h3> <p>目标任务: 能够说出组件的销毁阶段的钩子函数以及执行时机</p> <table><thead><tr><th>钩子函数</th> <th>触发时机</th> <th>作用</th></tr></thead> <tbody><tr><td>componentWillUnmount</td> <td>组件卸载（从页面中消失）</td> <td>执行清理工作（比如：清理定时器等）</td></tr></tbody></table> <h2 id="hooks-基础"><a href="#hooks-基础" class="header-anchor">#</a> Hooks 基础</h2> <hr> <h3 id="hooks-概念理解"><a href="#hooks-概念理解" class="header-anchor">#</a> Hooks 概念理解</h3> <hr> <p>本节任务: 能够理解 hooks 的概念及解决的问题</p> <p><strong>1. 什么是 hooks</strong></p> <p><strong>Hooks 的本质：一套能够使函数组件更强大，更灵活的“钩子”</strong></p> <p>React 体系里组件分为 <code>类组件</code> 和 <code>函数组件</code></p> <p>经过多年的实战，函数组件是一个更加匹配 React 的设计理念 UI = f(data)，也更有利于逻辑拆分与重用的组件表达形式，而先前的函数组件是不可以有自己的状态的，为了能让函数组件可以拥有自己的状态，所以从 react v16.8 开始，Hooks 应运而生</p> <p><strong>注意点：</strong></p> <ul><li>有了 hooks 之后，为了兼容老版本，class 类组件并没有被移除，俩者都可以使用</li> <li>有了 hooks 之后，不能在把函数成为无状态组件了，因为 hooks 为函数组件提供了状态</li> <li><strong>hooks 只能在函数组件中使用</strong></li></ul> <p><strong>2. Hooks 解决了什么问题</strong></p> <p>Hooks 的出现解决了俩个问题 :1. 组件的状态逻辑复用 2. class 组件自身的问题</p> <ul><li>1.组件的逻辑复用</li></ul> <p>在 hooks 出现之前，react 先后尝试了 mixins 混入，HOC 高阶组件，render-props 等模式
但是都有各自的问题，比如 mixin 的数据来源不清晰，高阶组件的嵌套问题等等</p> <ul><li>2.class 组件自身的问题</li></ul> <p>class 组件就像一个厚重的‘战舰’ 一样，大而全，提供了很多东西，有不可忽视的学习成本，比如各种生命周期，this 指向问题等等，而我们更多时候需要的是一个轻快灵活的'快艇'</p> <p><strong>3. Hooks 优势总结</strong></p> <ol><li>告别难以理解 Class</li> <li>解决业务逻辑难以拆分的问题</li> <li>使状态逻辑复用变得简单可行</li> <li>函数组件在设计思维上，更加契合 React 的理念</li></ol> <h3 id="usestate"><a href="#usestate" class="header-anchor">#</a> useState</h3> <hr> <p><strong>1. 基础使用</strong></p> <p><code>本节任务</code>: 能够学会 useState 的基础用法</p> <p><strong>作用</strong>
useState 为函数组件提供状态（state）</p> <p><strong>使用步骤</strong></p> <ol><li>导入 useState 函数</li> <li>调用 useState 函数，并传入状态的初始值</li> <li>从 useState 函数的返回值中，拿到状态和修改状态的方法</li> <li>在 JSX 中展示状态</li> <li>调用修改状态的方法更新状态</li></ol> <p><strong>代码实现</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// useState</span>
<span class="token comment">// 快速使用</span>
<span class="token comment">// 1.导入useState函数 react</span>
<span class="token comment">// 2.在函数组件的内部执行这个方法，并且传入一个初始值</span>
<span class="token comment">// 3.通过解构赋值 得到数据状态和一个修改数据状态的方法</span>
<span class="token comment">// 4.渲染数据状态 在某个时机下通过执行方法修改状态</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 可以自定义变量和函数名 顺序不可更改</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>age<span class="token punctuation">,</span> setAge<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">useState</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">// [0,f()]</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setAge</span><span class="token punctuation">(</span>age <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>age<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><p><strong>2. 状态的读取和修改</strong></p> <p>本节任务: 能够理解 useState 下状态的读取和修改</p> <p><strong>读取状态</strong></p> <p>该方式提供的状态，是函数内部的局部变量，可以在函数内的任意位置使用</p> <p><strong>修改状态</strong></p> <ol><li>setCount 是一个函数，参数表示最新的状态值</li> <li>调用该函数后，将使用新值替换旧值</li> <li>修改状态后，由于状态发生变化，会引起视图变化</li></ol> <p><strong>注意事项</strong></p> <p>修改状态的时候，一定要使用新的状态替换旧的状态，不能直接修改旧的状态，尤其是引用类型</p> <p><strong>3. 组件的更新过程</strong></p> <p><code>本节任务</code>: 能够理解使用 hook 之后组件的更新情况</p> <p>函数组件使用 useState hook 后的执行过程，以及状态值的变化</p> <ul><li>组件第一次渲染
<ul><li>从头开始执行该组件中的代码逻辑</li> <li>调用 <code>useState(0)</code> 将传入的参数作为状态初始值，即：0</li> <li>渲染组件，此时，获取到的状态 count 值为： 0</li></ul></li> <li>组件第二次渲染
<ul><li>点击按钮，调用 <code>setCount(count + 1)</code> 修改状态，因为状态发生改变，所以，该组件会重新渲染</li> <li>组件重新渲染时，会再次执行该组件中的代码逻辑</li> <li>再次调用 <code>useState(0)</code>，此时 React 内部会拿到最新的状态值而非初始值，比如，该案例中最新的状态值为 1</li> <li>再次渲染组件，此时，获取到的状态 count 值为：1</li></ul></li></ul> <p><strong>注意</strong>：</p> <blockquote><p>useState 的初始值(参数)只会在组件第一次渲染时生效。也就是说，以后的每次渲染，useState 获取到都是最新的状态值，React 组件会记住每次最新的状态值</p></blockquote> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> setCount<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
  <span class="token comment">// 在这里可以进行打印测试</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>count<span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span>
      <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token function">setCount</span><span class="token punctuation">(</span>count <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span>
      <span class="token punctuation">}</span><span class="token punctuation">}</span></span>
    <span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span>count<span class="token punctuation">}</span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><p><strong>4. 使用规则</strong></p> <p>本节任务: 能够记住 <code>useState</code> 的使用规则</p> <p><strong>useState 函数可以执行多次，每次执行互相独立，每调用一次为函数组件提供一个状态</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">function</span> <span class="token function">List</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 以字符串为初始值</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>name<span class="token punctuation">,</span> setName<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token string">'cp'</span><span class="token punctuation">)</span>
  <span class="token comment">// 以数组为初始值</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>list<span class="token punctuation">,</span> setList<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
  <span class="token comment">// 以布尔值为初始值</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>flag<span class="token punctuation">,</span> setFlag<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span>
  <span class="token comment">// 以number为初始值</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> setCount<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p><strong>useState 注意事项</strong></p> <ol><li>只能出现在函数组件最外层作用域或者其他 hook 函数中</li> <li>不能嵌套在 if/for/其它函数中（react 按照 hooks 的调用顺序识别每一个 hook）</li></ol> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">let</span> num <span class="token operator">=</span> <span class="token number">1</span>
<span class="token keyword">function</span> <span class="token function">List</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  num<span class="token operator">++</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>num <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token punctuation">[</span>name<span class="token punctuation">,</span> setName<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token string">'cp'</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>list<span class="token punctuation">,</span> setList<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// 俩个hook的顺序不是固定的，这是不可以的！！</span>
</code></pre></div><ol start="3"><li>可以通过开发者工具查看 hooks 状态</li></ol> <h3 id="useeffect"><a href="#useeffect" class="header-anchor">#</a> useEffect</h3> <ol><li><p>理解函数副作用</p> <p>本节任务: 能够理解副作用的概念</p> <p><strong>什么是副作用</strong></p> <blockquote><p><strong>副作用是相对于主作用来说的，一个函数除了主作用，其他的作用就是副作用。对于 React 组件来说，主作用就是根据数据（state/props）渲染 UI，除此之外都是副作用（比如，手动修改 DOM）</strong></p></blockquote> <p><strong>常见的副作用</strong></p> <ol><li>数据请求 ajax 发送</li> <li>手动修改 dom</li> <li>localstorage 操作</li></ol> <p><strong>useEffect 函数的作用就是为 react 函数组件提供副作用处理的！</strong></p></li> <li><p>基础使用</p> <p>本节任务: 能够学会 useEffect 的基础用法并且掌握默认的执行执行时机</p> <p><strong>作用</strong></p> <blockquote><p>为 react 函数组件提供副作用处理</p></blockquote> <p><strong>使用步骤</strong></p> <ol><li>导入 useEffect 函数</li> <li>调用 useEffect 函数，并传入回调函数</li> <li>在回调函数中编写副作用处理（dom 操作）</li> <li>修改数据状态</li> <li>检测副作用是否生效</li></ol> <p><strong>代码实现</strong></p></li></ol> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> useEffect<span class="token punctuation">,</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> setCount<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>

  <span class="token function">useEffect</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">// dom操作</span>
    document<span class="token punctuation">.</span>title <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">当前已点击了</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>count<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">次</span><span class="token template-punctuation string">`</span></span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span>
      <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token function">setCount</span><span class="token punctuation">(</span>count <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span>
      <span class="token punctuation">}</span><span class="token punctuation">}</span></span>
    <span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span>count<span class="token punctuation">}</span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><ol start="3"><li><p>依赖项控制执行时机
<code>本节任务</code>: 能够学会使用依赖项控制副作用的执行时机</p> <p><strong>1. 不添加依赖项</strong></p> <blockquote><p>组件首次渲染执行一次，以及不管是哪个状态更改引起组件更新时都会重新执行 1.组件初始渲染 2.组件更新 （不管是哪个状态引起的更新）</p></blockquote> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token function">useEffect</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'副作用执行了'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p><strong>2. 添加空数组</strong></p> <blockquote><p>组件只在首次渲染时执行一次</p></blockquote> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token function">useEffect</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'副作用执行了'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
</code></pre></div><p><strong>3. 添加特定依赖项</strong></p> <blockquote><p>副作用函数在首次渲染时执行，在依赖项发生变化时重新执行</p></blockquote> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> setCount<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>name<span class="token punctuation">,</span> setName<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token string">'zs'</span><span class="token punctuation">)</span>

  <span class="token function">useEffect</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'副作用执行了'</span><span class="token punctuation">)</span>
    document<span class="token punctuation">.</span>title <span class="token operator">=</span> count
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> name<span class="token punctuation">]</span><span class="token punctuation">)</span>
  <span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> 此时什么时候执行副作用函数？<span class="token number">1.</span> 组件首次渲染 <span class="token number">2.</span> 修改依赖数据时 count或者name会执行一次 <span class="token operator">--</span><span class="token operator">&gt;</span>

  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span>
        <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
          <span class="token function">setCount</span><span class="token punctuation">(</span>count <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span><span class="token punctuation">}</span></span>
      <span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span>count<span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span>
        <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
          <span class="token function">setName</span><span class="token punctuation">(</span><span class="token string">'cp'</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span><span class="token punctuation">}</span></span>
      <span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span>name<span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span></span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p><strong>注意事项</strong></p> <p>useEffect 回调函数中用到的数据（比如，count）就是依赖数据，就应该出现在依赖项数组中，如果不添加依赖项就会有 bug 出现
某种意义上，hooks 的出现，就是想不用生命周期也可以写业务代码</p> <p><strong>4. 清理副作用</strong></p> <blockquote><p>如果想要清理副作用 可以在副作用函数中的末尾 return 一个新的函数，在新的函数中编写清理副作用的逻辑
注意执行时机为：</p></blockquote> <ol><li>组件卸载时自动执行</li> <li>组件更新时，下一个 useEffect 副作用函数执行之前自动执行</li></ol></li></ol> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> useEffect<span class="token punctuation">,</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token keyword">const</span> <span class="token function-variable function">App</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> setCount<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
  <span class="token function">useEffect</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> timerId <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token function">setCount</span><span class="token punctuation">(</span>count <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token comment">// 用来清理副作用的事情</span>
      <span class="token function">clearInterval</span><span class="token punctuation">(</span>timerId<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>count<span class="token punctuation">]</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>count<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h3 id="阶段小练习-自定义-hook"><a href="#阶段小练习-自定义-hook" class="header-anchor">#</a> 阶段小练习 - 自定义 hook</h3> <p>需求描述：自定义一个 hook 函数，实现获取滚动距离 Y
<code>const [y] = useWindowScroll()</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">//   /hooks/useScroll.js</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">useWindowScroll</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>y<span class="token punctuation">,</span> setY<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
  window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'scroll'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> h <span class="token operator">=</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>scrollTop
    <span class="token function">setY</span><span class="token punctuation">(</span>h<span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">[</span>y<span class="token punctuation">]</span>
<span class="token punctuation">}</span>

<span class="token comment">// 导入useWindowScroll</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> useWindowScroll <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'./hooks/useScroll'</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>y<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useWindowScroll</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> height<span class="token operator">:</span> <span class="token string">'12000px'</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      // 此时打开控制台，寻找元素 ,看到数据变化
      </span><span class="token punctuation">{</span>y<span class="token punctuation">}</span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><p><strong>需求描述</strong>： 自定义 hook 函数，可以自动同步到本地 LocalStorage</p> <blockquote><p>const [message, setMessage] = useLocalStorage(key，defaultValue)</p></blockquote> <ol><li>message 可以通过自定义传入默认初始值</li> <li>每次修改 message 数据的时候 都会自动往本地同步一份</li></ol> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> useEffect<span class="token punctuation">,</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">useLocalStorage</span><span class="token punctuation">(</span><span class="token parameter">key<span class="token punctuation">,</span> defaultValue</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>message<span class="token punctuation">,</span> setMessage<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span>defaultValue<span class="token punctuation">)</span>
  <span class="token comment">// 每次只要message变化 就会自动同步到本地ls</span>
  <span class="token function">useEffect</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    window<span class="token punctuation">.</span>localStorage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> message<span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>message<span class="token punctuation">,</span> key<span class="token punctuation">]</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">[</span>message<span class="token punctuation">,</span> setMessage<span class="token punctuation">]</span>
<span class="token punctuation">}</span>

<span class="token comment">// 导入useLocalStorage</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> useLocalStorage <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'./hooks/useLocal'</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>message<span class="token punctuation">,</span> setMessage<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useLocalStorage</span><span class="token punctuation">(</span><span class="token string">'hook-key'</span><span class="token punctuation">,</span> <span class="token string">'zsc'</span><span class="token punctuation">)</span>
  <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token function">setMessage</span><span class="token punctuation">(</span><span class="token string">'赵泽锡'</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">5000</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>div style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> height<span class="token operator">:</span> <span class="token string">'12000px'</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">&gt;</span><span class="token punctuation">{</span>message<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h2 id="hooks-进阶"><a href="#hooks-进阶" class="header-anchor">#</a> Hooks 进阶</h2> <hr> <h3 id="usestate-回调函数的参数"><a href="#usestate-回调函数的参数" class="header-anchor">#</a> useState - 回调函数的参数</h3> <p><code>本节任务</code>: 能够理解 useState 回调函数作为参数的使用场景</p> <p><strong>1. 使用场景</strong></p> <p>参数只会在组件的初始渲染中起作用，后续渲染时会被忽略。如果初始 state 需要通过计算才能获得，则可以传入一个函数，在函数中计算并返回初始的 state，此函数只在初始渲染时被调用</p> <p><strong>2.语法</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">const</span> <span class="token punctuation">[</span>name<span class="token punctuation">,</span> setName<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// 编写计算逻辑    return '计算之后的初始值'</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p><strong>3.语法规则</strong></p> <ul><li><ol><li>回调函数 return 出去的值将作为 name 的初始值</li></ol></li> <li><ol start="2"><li>回调函数中的逻辑只会在组件初始化的时候执行一次</li></ol></li></ul> <p><strong>4.语法选择</strong></p> <ul><li><ol><li>如果就是初始化一个普通的数据 直接使用 useState(普通数据) 即可</li></ol></li> <li><ol start="2"><li>如果要初始化的数据无法直接得到需要通过计算才能获取到，使用 useState(()=&gt;{})</li></ol></li></ul> <p><strong>4.来个需求</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token keyword">function</span> <span class="token function">getDefaultValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 10000天数据</span>
  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">10000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token string">'10'</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">Counter</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> setCount<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">// return props.count</span>
    <span class="token comment">// 计算数据</span>
    <span class="token keyword">return</span> <span class="token function">getDefaultValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setCount</span><span class="token punctuation">(</span>count <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>count<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Counter</span></span> <span class="token attr-name">count</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token number">10</span><span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Counter</span></span> <span class="token attr-name">count</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token number">20</span><span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span></span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h3 id="useeffect-发送网络请求"><a href="#useeffect-发送网络请求" class="header-anchor">#</a> useEffect - 发送网络请求</h3> <p><code>本节任务</code>: 能够掌握使用 useEffect hook 发送网络请求</p> <p><strong>1.使用场景</strong>
如何在 useEffect 中发送网络请求，并且封装同步 async await 操作</p> <p><strong>2.语法要求</strong></p> <p>不可以直接在 useEffect 的回调函数外层直接包裹 await ，因为异步会导致清理函数无法立即返回</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token function">useEffect</span><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> res <span class="token operator">=</span> <span class="token keyword">await</span> axios<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'http://geek.itheima.net/v1_0/channels'</span><span class="token punctuation">)</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
</code></pre></div><p><strong>3 正确写法</strong></p> <p>在内部单独定义一个函数，然后把这个函数包装成同步</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token function">useEffect</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
    <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">fetchData</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
       <span class="token keyword">const</span> res <span class="token operator">=</span> <span class="token keyword">await</span> axios<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'http://geek.itheima.net/v1_0/channels'</span><span class="token punctuation">)</span>                            console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
</code></pre></div><h3 id="useref"><a href="#useref" class="header-anchor">#</a> <strong>useRef</strong></h3> <p><code>本节任务</code>: 能够掌握使用 useRef 获取真实 dom 或组件实例的方法</p> <p><strong>使用场景</strong></p> <p>在函数组件中获取真实的 dom 元素对象或者是组件对象</p> <ol><li><p><strong>使用步骤</strong></p> <ul><li><ol><li>导入 useRef 函数</li></ol></li> <li><ol start="2"><li>执行 useRef 函数并传入 null，返回值为一个对象 内部有一个 <code>current</code> 属性存放拿到的 dom 对象（组件实例）</li></ol></li> <li><ol start="3"><li>通过 ref 绑定 要获取的元素或者组件</li></ol></li></ul></li> <li><p>获取 dom</p></li></ol> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> useEffect<span class="token punctuation">,</span> useRef <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> h1Ref <span class="token operator">=</span> <span class="token function">useRef</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span>
  <span class="token function">useEffect</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>h1Ref<span class="token punctuation">.</span>current<span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span> <span class="token attr-name">ref</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>h1Ref<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">this is h1</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><ol start="3"><li>获取组件实例</li></ol> <p>函数组件由于没有实例，不能使用 ref 获取，如果想获取组件实例，必须是类组件</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">class</span> <span class="token class-name">Foo</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'say hi'</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Foo</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> Foo

<span class="token keyword">import</span> <span class="token punctuation">{</span> useEffect<span class="token punctuation">,</span> useRef <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">import</span> Foo <span class="token keyword">from</span> <span class="token string">'./Foo'</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> h1Foo <span class="token operator">=</span> <span class="token function">useRef</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span>
  <span class="token comment">// useEffect回调是dom渲染之后执行，获取dom</span>
  <span class="token function">useEffect</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>h1Foo<span class="token punctuation">.</span>current<span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token string">' '</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Foo</span></span> <span class="token attr-name">ref</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>h1Foo<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h3 id="usecontext"><a href="#usecontext" class="header-anchor">#</a> <strong>useContext</strong></h3> <p><code>本节任务</code>: 能够掌握 hooks 下的 context 使用方式</p> <p><strong>实现步骤</strong></p> <ol><li>使用 <code>createContext</code> 创建 <code>Context</code> 对象</li> <li>在顶层组件通过 <code>Provider</code> 提供数据</li> <li>在底层组件通过 <code>useContext</code> 函数获取数据</li></ol> <p><strong>代码实现</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> createContext<span class="token punctuation">,</span> useContext <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token comment">// 创建Context对象</span>
<span class="token keyword">const</span> Context <span class="token operator">=</span> <span class="token function">createContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token keyword">function</span> <span class="token function">Foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> count <span class="token operator">=</span> <span class="token function">useContext</span><span class="token punctuation">(</span>Context<span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      Foo </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Bar</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span>count<span class="token punctuation">}</span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">Bar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 底层组件通过useContext函数获取数据</span>
  <span class="token keyword">const</span> count <span class="token operator">=</span> <span class="token function">useContext</span><span class="token punctuation">(</span>Context<span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Bar </span><span class="token punctuation">{</span>count<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> setCount<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token comment">// 顶层组件通过Provider 提供数据</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Context.Provider</span></span> <span class="token attr-name">value</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>count<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Foo</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setCount</span><span class="token punctuation">(</span>count <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">+</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Context.Provider</span></span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><p><img src="http://zscnb.gitee.io/upload/static/img/app1.png" draggable="false" alt="image-20201026174611477"></p> <p><img src="http://zscnb.gitee.io/upload/static/img/app.png" draggable="false" alt="image-20201026174611477"></p> <h2 id="react-router"><a href="#react-router" class="header-anchor">#</a> React-Router</h2> <h3 id="前置知识"><a href="#前置知识" class="header-anchor">#</a> 前置知识</h3> <div class="language- extra-class"><pre><code>1. 单页应用

只有一个html文件  主流的开发模式变成了通过路由进行页面切换 优势: 避免整体页面刷新  用户体验变好
 前端负责事情变多了  开发的难度变大
2. 路由的本质
</code></pre></div><p>概念来源于后端 : 一个路径表示匹配一个服务器资源 /a.html -&gt; a 对应的文件资源 /b.html -&gt; b 对应的文件资源
共同的思想: 一对一的关系
前端的路由: 一个路径 path 对应唯一的一个组件 comonent 当我们访问一个 path 自动把 path 对应的组件进行渲染</p> <div class="language-JS extra-class"><pre class="language-js"><code><span class="token keyword">const</span> routes <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    path<span class="token operator">:</span><span class="token string">'/home'</span><span class="token punctuation">,</span>
    component<span class="token operator">:</span> Home
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
   <span class="token punctuation">{</span>
    path<span class="token operator">:</span><span class="token string">'/about'</span><span class="token punctuation">,</span>
    component<span class="token operator">:</span> About
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
   <span class="token punctuation">{</span>
    path<span class="token operator">:</span><span class="token string">'/article'</span><span class="token punctuation">,</span>
    component<span class="token operator">:</span> Article
  <span class="token punctuation">}</span>
<span class="token punctuation">]</span>
</code></pre></div><h3 id="_1-准备项目环境"><a href="#_1-准备项目环境" class="header-anchor">#</a> 1. 准备项目环境</h3> <p>create-react-app -&gt; cra -&gt; webpack
vite: 可以实现 cra 同等能力 但是速度更快的打包工具 [尤大]
使用 vite 新增一个 React 项目，然后安装一个 v6 版本的 react-router-dom</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token comment"># 创建react项目</span>
<span class="token function">yarn</span> create vite react-router --template react

<span class="token comment"># 安装所有依赖包</span>
<span class="token function">yarn</span>

<span class="token comment"># 启动项目</span>
<span class="token function">yarn</span> dev

<span class="token comment"># 安装react-router包</span>
<span class="token function">yarn</span> <span class="token function">add</span> react-router-dom@6
</code></pre></div><h3 id="_2-基础使用"><a href="#_2-基础使用" class="header-anchor">#</a> 2. 基础使用</h3> <p><strong>需求: 准备俩个按钮，点击不同按钮切换不同组件内容的显示</strong></p> <p>实现步骤：</p> <ol><li>导入必要的路由 router 内置组件</li> <li>准备俩个 React 组件</li> <li>按照路由的规则进行路由配置</li></ol> <p><img src="http://zscnb.gitee.io/upload/static/img/case.png" draggable="false" alt="image-20201026174611477"></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 引入必要的内置组件</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> BrowserRouter<span class="token punctuation">,</span> Routes<span class="token punctuation">,</span> Route<span class="token punctuation">,</span> Link <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-router-dom'</span>

<span class="token comment">// 准备俩个路由组件</span>

<span class="token keyword">const</span> <span class="token function-variable function">Home</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">this is home</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token keyword">const</span> <span class="token function-variable function">About</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">this is about</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token comment">/* 按照规则配置路由 */</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">BrowserRouter</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">首页</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/about<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">关于</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Routes</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
          </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/<span class="token punctuation">&quot;</span></span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Home</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Route</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
          </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/about<span class="token punctuation">&quot;</span></span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">About</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Route</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Routes</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">BrowserRouter</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App
</code></pre></div><h3 id="_3-核心内置组件说明"><a href="#_3-核心内置组件说明" class="header-anchor">#</a> 3. 核心内置组件说明</h3> <ol><li><p><code>BrowerRouter</code>
作用: 包裹整个应用，一个 React 应用只需要使用一次</p> <table><thead><tr><th>模式</th> <th>实现方式</th> <th>路由 url 表现</th></tr></thead> <tbody><tr><td>HashRouter</td> <td>监听 url hash 值实现</td> <td>http://localhost:3000/#/about</td></tr> <tr><td>BrowerRouter</td> <td>h5 的 history.pushState API 实现</td> <td>http://localhost:3000/about</td></tr></tbody></table></li> <li><p>Link</p> <p>作用: 用于指定导航链接，完成声明式的路由跳转 类似于 vue 的 <code>&lt;router-link/&gt;</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/path<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">首页</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>这里 to 属性用于指定路由地址，表示要跳转到哪里去，Link 组件最终会被渲染为原生的 a 链接</p></li> <li><p>Routes
作用: 提供一个路由出口，组件内部会存在多个内置的 Route 组件，满足条件的路由会被渲染到组件内部
类比 vue 中<code>router-view</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Routes</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
  </span><span class="token punctuation">{</span><span class="token comment">/*满足条件的路由会被渲染到组件内部*/</span><span class="token punctuation">}</span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/<span class="token punctuation">&quot;</span></span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Home</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Route</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/about<span class="token punctuation">&quot;</span></span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">About</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Route</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Routes</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div></li> <li><p>Route
作用: 用于定义路由路径和渲染组件的对应关系 [element：因为 react 体系内 把组件叫做 <code>react element</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Routes</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/about<span class="token punctuation">&quot;</span></span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">About</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Route</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Routes</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>其中 path 属性用来指定匹配的路径地址，<code>element</code> 属性指定要渲染的组件，图中配置的意思为: 当 <code>url</code> 上访问的地址为 /about 时，当前路由发生匹配，对应的 <code>About</code> 组件渲染</p></li></ol> <h3 id="_4-编程式导航"><a href="#_4-编程式导航" class="header-anchor">#</a> 4. 编程式导航</h3> <p>声明式 <code>【 Link to】</code> vs 编程式 【调用路由方法进行路由跳转】</p> <p>概念: 通过 <code>js</code> 编程的方式进行路由页面跳转，比如说从首页跳转到关于页</p> <p><strong>实现步骤：</strong></p> <ul><li>导入一个 <code>useNavigate</code> 钩子函数</li> <li>执行 <code>useNavigate</code> 函数 得到 跳转函数</li> <li>在事件中执行跳转函数完成路由跳转</li></ul> <div class="language-jsx extra-class"><pre class="language-jsx"><code>pages <span class="token operator">/</span> Home<span class="token punctuation">.</span>js

<span class="token comment">// 导入useNavigate函数</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> useNavigate <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-router-dom'</span>
<span class="token keyword">const</span> <span class="token function-variable function">Home</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// 执行函数</span>
  <span class="token keyword">const</span> navigate <span class="token operator">=</span> <span class="token function">useNavigate</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      Home
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">navigate</span><span class="token punctuation">(</span><span class="token string">'/about'</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"> 跳转关于页 </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> Home
</code></pre></div><p><strong>注</strong>: 如果在跳转时不想添加历史记录，可以添加额外参数 <code>replace</code> 为<code>true</code></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token function">navigate</span><span class="token punctuation">(</span><span class="token string">'/about'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> replace<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><h3 id="_5-路由传参"><a href="#_5-路由传参" class="header-anchor">#</a> 5. 路由传参</h3> <p>场景：跳转路由的同时，有时候要需要传递参数</p> <ul><li><ol><li>searchParams 传参</li></ol></li></ul> <p><strong>路由传参</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token function">navigate</span><span class="token punctuation">(</span><span class="token string">'/about?id=1001&amp;name=zsc'</span><span class="token punctuation">)</span>
</code></pre></div><p><strong>路由取参</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> useSearchParams <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-router-dom'</span>
<span class="token keyword">let</span> <span class="token punctuation">[</span>params<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useSearchParams</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">let</span> id <span class="token operator">=</span> params<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'id'</span><span class="token punctuation">)</span>
<span class="token keyword">let</span> name <span class="token operator">=</span> params<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'name'</span><span class="token punctuation">)</span>
</code></pre></div><ul><li><ol start="2"><li>params 传参</li></ol></li></ul> <p><strong>路由传参</strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">;</span><span class="token operator">&lt;</span>Routes<span class="token operator">&gt;</span>
  <span class="token operator">&lt;</span>Route path<span class="token operator">=</span><span class="token string">&quot;/about/:id&quot;</span> element<span class="token operator">=</span><span class="token punctuation">{</span><span class="token operator">&lt;</span>About <span class="token operator">/</span><span class="token operator">&gt;</span><span class="token punctuation">}</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>Route<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>Routes<span class="token operator">&gt;</span>

<span class="token function">navigate</span><span class="token punctuation">(</span><span class="token string">'/about/1001'</span><span class="token punctuation">)</span>
</code></pre></div><p><strong>路由取参</strong></p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> useParams <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-router-dom'</span>
<span class="token keyword">let</span> <span class="token punctuation">[</span>params<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useParams</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">let</span> id <span class="token operator">=</span> params<span class="token punctuation">.</span>id
</code></pre></div><h3 id="_6-嵌套路由"><a href="#_6-嵌套路由" class="header-anchor">#</a> 6. 嵌套路由</h3> <p>场景：在我们做的很多的管理后台系统中，通常我们都会设计一个 <code>Layout</code> 组件，在它内部实现嵌套路由</p> <p><img src="http://zscnb.gitee.io/upload/static/img/case1.png" draggable="false" alt="image-20201026174611477"></p> <p><strong>实现步骤：</strong></p> <p>App.js 中定义嵌套路由声明
Layout 组件内部通过 <code>&lt;Outlet/&gt;</code> 指定二级路由出口</p> <ol><li><ul><li>App.js 组件中定义路由嵌套关系</li></ul></li></ol> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">//App.jsx</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Routes</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/<span class="token punctuation">&quot;</span></span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Layout</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>board<span class="token punctuation">&quot;</span></span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Board</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article<span class="token punctuation">&quot;</span></span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Article</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Route</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
  </span><span class="token punctuation">{</span><span class="token comment">/* 省略部分  */</span><span class="token punctuation">}</span><span class="token plain-text">
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Routes</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ol start="2"><li><ul><li>Layout.js 组件中使用 Outlet 组件添加二级路由出口</li></ul></li></ol> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">//Layout.jsx</span>

<span class="token keyword">import</span> <span class="token punctuation">{</span> Outlet <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-router-dom'</span>

<span class="token keyword">const</span> <span class="token function-variable function">Layout</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      layout
      </span><span class="token punctuation">{</span><span class="token comment">/* 二级路由的path等于 一级path + 二级path  */</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/board<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">board</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/article<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">article</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token comment">/* 二级路由出口 */</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Outlet</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> Layout
</code></pre></div><h3 id="_7-默认二级路由"><a href="#_7-默认二级路由" class="header-anchor">#</a> 7. 默认二级路由</h3> <p><strong>场景: 应用首次渲染完毕就需要显示的二级路由</strong></p> <p><strong>实现步骤:</strong></p> <ol><li>给默认二级路由标记<code>index</code>属性</li> <li>把原本的路径<code>path属</code>性去掉</li></ol> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token punctuation">;</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Routes</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/<span class="token punctuation">&quot;</span></span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Layout</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">index</span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Board</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article<span class="token punctuation">&quot;</span></span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Article</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Route</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Routes</span></span><span class="token punctuation">&gt;</span></span>

<span class="token keyword">import</span> <span class="token punctuation">{</span> Outlet <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-router-dom'</span>

<span class="token keyword">const</span> <span class="token function-variable function">Layout</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      layout
      </span><span class="token punctuation">{</span><span class="token comment">/* 默认二级不再具有自己的路径  */</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">board</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/article<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">article</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token comment">/* 二级路由出口 */</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Outlet</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="_8-404-路由配置"><a href="#_8-404-路由配置" class="header-anchor">#</a> 8. 404 路由配置</h3> <p><strong>场景：当 url 的路径在整个路由配置中都找不到对应的 path，使用 404 兜底组件进行渲染</strong></p> <p>准备一个 NotFound 组件</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">const</span> <span class="token function-variable function">NotFound</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">this is NotFound</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> NotFound
</code></pre></div><div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">BrowserRouter</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Routes</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/<span class="token punctuation">&quot;</span></span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Layout</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      // 默认渲染二级路由
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">index</span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Board</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article<span class="token punctuation">&quot;</span></span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Article</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Route</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>\*<span class="token punctuation">&quot;</span></span> <span class="token attr-name">element</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">NotFound</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Route</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Routes</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">BrowserRouter</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><strong>尝试访问一个不存在的路径，查看效果~</strong></p> <h2 id="mobx"><a href="#mobx" class="header-anchor">#</a> Mobx</h2> <h3 id="_1-mobx-介绍"><a href="#_1-mobx-介绍" class="header-anchor">#</a> 1. Mobx 介绍</h3> <p>一个可以和 React 良好配合的集中状态管理工具，和 Redux 解决的问题相似，都可以独立组件进行集中状态管理</p> <p><img src="http://zscnb.gitee.io/upload/static/img/mobx1.png" draggable="false" alt="image-20201026174611477"></p> <p><strong>优势</strong></p> <ul><li><ol><li><span style="color:#f40;">简单</span></li></ol> <p>编写无模板的极简代码精准描述你的意图</p></li> <li><ol start="2"><li><span style="color:#f40;">轻松实现最优渲染</span></li></ol> <p>依赖自动追踪，实现最小渲染优化</p></li> <li><ol start="3"><li><span style="color:#f40;">架构自由</span></li></ol> <p>可移植, 可测试 无特殊心智负担</p></li></ul> <p><strong>社区评价</strong></p> <p><img src="http://zscnb.gitee.io/upload/static/img/mobx2.png" draggable="false" alt="image-20201026174611477"></p> <h3 id="_2-配置开发环境"><a href="#_2-配置开发环境" class="header-anchor">#</a> 2. 配置开发环境</h3> <p><strong>Mobx 是一个独立的响应式的库，可以独立于任何 UI 框架存在，但是通常大家习惯把它和 React 进行绑定使用，用 Mobx 来做响应式数据建模，React 作为 UI 视图框架渲染内容，我们环境的配置需要三个部分</strong></p> <ul><li>一个 <code>create-react-app</code> 创建好的 <code>React</code> 项目环境</li> <li>mobx 框架本身</li> <li>一个用来链接 <code>mobx</code> 和 <code>React</code> 的中间件</li></ul> <h3 id="_3-基础使用"><a href="#_3-基础使用" class="header-anchor">#</a> 3. 基础使用</h3> <blockquote><p>需求: 使用 mobx 实现一个计数器的案例</p></blockquote> <p><img src="http://zscnb.gitee.io/upload/static/img/mobx3.png" draggable="false" alt="image-20201026174611477"></p> <ul><li><p><strong>初始化 mobx</strong></p> <p>初始化步骤:</p> <ul><li>定义数据状态 <code>state</code></li> <li>在构造器中实现数据响应式处理 <code>makeAutoObservble</code></li> <li>定义修改数据的函数 <code>action</code></li> <li>实例化 <code>store</code> 并导出</li></ul></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> makeAutoObservable <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'mobx'</span>

<span class="token keyword">class</span> <span class="token class-name">CounterStore</span> <span class="token punctuation">{</span>
  count <span class="token operator">=</span> <span class="token number">0</span> <span class="token comment">// 定义数据</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">makeAutoObservable</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span> <span class="token comment">// 响应式处理</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 定义修改数据的方法</span>
  <span class="token function-variable function">addCount</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>count<span class="token operator">++</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> counter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">CounterStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span> counter <span class="token punctuation">}</span>
</code></pre></div><ul><li><p><strong>React 使用 store</strong></p> <p>实现步骤:</p> <ul><li>在组件中导入 <code>counterStore</code> 实例对象</li> <li>在组件中使用 <code>storeStore</code> 实例对象中的数据</li> <li>通过事件调用修改数据的方法修改 <code>store</code> 中的数据</li> <li>让组件响应数据变化</li></ul></li></ul> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 导入counterStore</span>
<span class="token keyword">import</span> counterStore <span class="token keyword">from</span> <span class="token string">'./store'</span>
<span class="token comment">// 通过mobx-react-lite中间件导入observer方法</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> observer <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'mobx-react-lite'</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> counterStore<span class="token punctuation">.</span><span class="token function">addCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span>counterStore<span class="token punctuation">.</span>count<span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// 包裹组件让视图响应数据变化</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">observer</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span>
</code></pre></div><h3 id="_4-计算属性-衍生状态"><a href="#_4-计算属性-衍生状态" class="header-anchor">#</a> 4. 计算属性（衍生状态）</h3> <p>概念: 有一些状态根据现有的状态计算（衍生）得到，我们把这种状态叫做计算属性, 看下面的例子</p> <p><img src="http://zscnb.gitee.io/upload/static/img/mobx4.png" draggable="false" alt="image-20201026174611477"></p> <p><strong>实现步骤：</strong></p> <ul><li>声明一个存在的数据</li> <li>通过 get 关键词 定义计算属性</li> <li>在 <code>makeAutoObservable</code> 方法中标记计算属性</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> computed<span class="token punctuation">,</span> makeAutoObservable <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'mobx'</span>

<span class="token keyword">class</span> <span class="token class-name">CounterStore</span> <span class="token punctuation">{</span>
  list <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">]</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">makeAutoObservable</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
      filterList<span class="token operator">:</span> computed<span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 修改原数组</span>
  <span class="token function-variable function">changeList</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 定义计算属性</span>
  <span class="token keyword">get</span> <span class="token function">filterList</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> item <span class="token operator">&gt;</span> <span class="token number">4</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> counter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">CounterStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> counter
</code></pre></div><div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token comment">// 导入 counterStore</span>
<span class="token keyword">import</span> counterStore <span class="token keyword">from</span> <span class="token string">'./store'</span>
<span class="token comment">// 导入 observer 方法</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> observer <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'mobx-react-lite'</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token regex">/_ 原数组 _/</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>counterStore<span class="token punctuation">.</span>list<span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token regex">/_ 计算属性 _/</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>counterStore<span class="token punctuation">.</span>filterList<span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> counterStore<span class="token punctuation">.</span><span class="token function">changeList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">change list</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// 包裹组件让视图响应数据变化</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">observer</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span>
</code></pre></div><h3 id="_5-异步数据处理"><a href="#_5-异步数据处理" class="header-anchor">#</a> 5. 异步数据处理</h3> <p>测试接口: http://geek.itheima.net/v1_0/channels</p> <blockquote><p>实现步骤:</p></blockquote> <ol><li>在 mobx 中编写异步请求方法 获取数据 存入 <code>state</code> 中</li> <li>组件中通过 <code>useEffect + 空依赖</code> 触发 <code>action</code> 函数的执行</li></ol> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 异步的获取</span>

<span class="token keyword">import</span> <span class="token punctuation">{</span> makeAutoObservable <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'mobx'</span>
<span class="token keyword">import</span> axios <span class="token keyword">from</span> <span class="token string">'axios'</span>

<span class="token keyword">class</span> <span class="token class-name">ChannelStore</span> <span class="token punctuation">{</span>
  channelList <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">makeAutoObservable</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 只要调用这个方法 就可以从后端拿到数据并且存入channelList</span>
  <span class="token function-variable function">setChannelList</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> res <span class="token operator">=</span> <span class="token keyword">await</span> axios<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'http://geek.itheima.net/v1_0/channels'</span><span class="token punctuation">)</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>channelList <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>channels
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">const</span> channlStore <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ChannelStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> channlStore
</code></pre></div><div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> useEffect <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> useStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'./store'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> observer <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'mobx-react-lite'</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">{</span> channlStore <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">useStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token comment">// 1. 使用数据渲染组件</span>
  <span class="token comment">// 2. 触发action函数发送异步请求</span>
  <span class="token function">useEffect</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    channlStore<span class="token punctuation">.</span><span class="token function">setChannelList</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span>channlStore<span class="token punctuation">.</span>channelList<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>item<span class="token punctuation">.</span>id<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>item<span class="token punctuation">.</span>name<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
      <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// 让组件可以响应数据的变化[也就是数据一变组件重新渲染]</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">observer</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span>
</code></pre></div><h3 id="_6-模块化"><a href="#_6-模块化" class="header-anchor">#</a> 6. 模块化</h3> <p>景: 一个项目有很多的业务模块，我们不能把所有的代码都写到一起，这样不好维护，提了提供可维护性，需要引入模块化机制</p> <p><img src="http://zscnb.gitee.io/upload/static/img/mobx5.png" draggable="false" alt="image-20201026174611477"></p> <p>实现步骤:</p> <ul><li><p>拆分模块 <code>js</code> 文件，每个模块中定义自己独立的 <code>state/action</code></p></li> <li><p><code>在 store/index.js</code> 中导入拆分之后的模块，进行模块组合</p></li> <li><p>利用 React 的 <code>context</code> 的机制导出统一的 <code>useStore</code> 方法，给业务组件使用</p></li> <li><p>1- 定义 task 模块</p></li></ul> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> makeAutoObservable <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'mobx'</span>

<span class="token keyword">class</span> <span class="token class-name">TaskStore</span> <span class="token punctuation">{</span>
  taskList <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">makeAutoObservable</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token function">addTask</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>taskList<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">'vue'</span><span class="token punctuation">,</span> <span class="token string">'react'</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> task <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TaskStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> task
</code></pre></div><ul><li>2- 定义 counterStore</li></ul> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> makeAutoObservable <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'mobx'</span>

<span class="token keyword">class</span> <span class="token class-name">CounterStore</span> <span class="token punctuation">{</span>
  count <span class="token operator">=</span> <span class="token number">0</span>
  list <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">]</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">makeAutoObservable</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token function-variable function">addCount</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>count<span class="token operator">++</span>
  <span class="token punctuation">}</span>
  <span class="token function-variable function">changeList</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">get</span> <span class="token function">filterList</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> item <span class="token operator">&gt;</span> <span class="token number">4</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> counter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">CounterStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> counter
</code></pre></div><ul><li>3- 组合模块导出统一方法</li></ul> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token keyword">import</span> counter <span class="token keyword">from</span> <span class="token string">'./counterStore'</span>
<span class="token keyword">import</span> task <span class="token keyword">from</span> <span class="token string">'./taskStore'</span>

<span class="token keyword">class</span> <span class="token class-name">RootStore</span> <span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>counterStore <span class="token operator">=</span> counter
    <span class="token keyword">this</span><span class="token punctuation">.</span>taskStore <span class="token operator">=</span> task
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> rootStore <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">RootStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token comment">// context机制的数据查找链  Provider如果找不到 就找createContext方法执行时传入的参数</span>
<span class="token keyword">const</span> context <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token function">createContext</span><span class="token punctuation">(</span>rootStore<span class="token punctuation">)</span>

<span class="token keyword">const</span> <span class="token function-variable function">useStore</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> React<span class="token punctuation">.</span><span class="token function">useContext</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span>
<span class="token comment">// useStore() =&gt;  rootStore  { counterStore, taskStore }</span>

<span class="token keyword">export</span> <span class="token punctuation">{</span> useStore <span class="token punctuation">}</span>
</code></pre></div><ul><li>4- 组件使用模块中的数据</li></ul> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> observer <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'mobx-react-lite'</span>
<span class="token comment">// 导入方法</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> useStore <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'./store'</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 得到store</span>
  <span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">useStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> store<span class="token punctuation">.</span>counterStore<span class="token punctuation">.</span><span class="token function">addCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span>store<span class="token punctuation">.</span>counterStore<span class="token punctuation">.</span>count<span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// 包裹组件让视图响应数据变化</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">observer</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span>
</code></pre></div></div> <footer class="page-edit" style="display:none;"><div class="edit-link"><a href="https://github.com/zscnb/blog/edit/master/docs/views/blog/react-base.md" target="_blank" rel="noopener noreferrer">HELP ME</a> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></div> <div class="last-updated"><span class="prefix">Last Updated: </span> <span class="time"> 2023/08/21 10:48:41</span></div></footer> <!----> <!----> <!----></main> <!----></div></div></div></div><div class="global-ui"><div class="back-to-ceiling" style="right:1rem;bottom:6rem;width:2.5rem;height:2.5rem;border-radius:.25rem;line-height:2.5rem;display:none;" data-v-c6073ba8 data-v-c6073ba8><svg t="1574745035067" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5404" class="icon" data-v-c6073ba8><path d="M526.60727968 10.90185116a27.675 27.675 0 0 0-29.21455937 0c-131.36607665 82.28402758-218.69155461 228.01873535-218.69155402 394.07834331a462.20625001 462.20625001 0 0 0 5.36959153 69.94390903c1.00431239 6.55289093-0.34802892 13.13561351-3.76865779 18.80351572-32.63518765 54.11355614-51.75690182 118.55860487-51.7569018 187.94566865a371.06718723 371.06718723 0 0 0 11.50484808 91.98906777c6.53300375 25.50556257 41.68394495 28.14064038 52.69160883 4.22606766 17.37162448-37.73630017 42.14135425-72.50938081 72.80769204-103.21549295 2.18761121 3.04276886 4.15646224 6.24463696 6.40373557 9.22774369a1871.4375 1871.4375 0 0 0 140.04691725 5.34970492 1866.36093723 1866.36093723 0 0 0 140.04691723-5.34970492c2.24727335-2.98310674 4.21612437-6.18497483 6.3937923-9.2178004 30.66633723 30.70611158 55.4360664 65.4791928 72.80769147 103.21549355 11.00766384 23.91457269 46.15860503 21.27949489 52.69160879-4.22606768a371.15156223 371.15156223 0 0 0 11.514792-91.99901164c0-69.36717486-19.13165746-133.82216804-51.75690182-187.92578088-3.42062944-5.66790279-4.76302748-12.26056868-3.76865837-18.80351632a462.20625001 462.20625001 0 0 0 5.36959269-69.943909c-0.00994388-166.08943902-87.32547796-311.81420293-218.6915546-394.09823051zM605.93803103 357.87693858a93.93749974 93.93749974 0 1 1-187.89594924 6.1e-7 93.93749974 93.93749974 0 0 1 187.89594924-6.1e-7z" p-id="5405" data-v-c6073ba8></path><path d="M429.50777625 765.63860547C429.50777625 803.39355007 466.44236686 1000.39046097 512.00932183 1000.39046097c45.56695499 0 82.4922232-197.00623328 82.5015456-234.7518555 0-37.75494459-36.9345906-68.35043303-82.4922232-68.34111062-45.57627738-0.00932239-82.52019037 30.59548842-82.51086798 68.34111062z" p-id="5406" data-v-c6073ba8></path></svg></div><!----><!----><div class="copydialog" style="display:none;" data-v-31384c7b data-v-31384c7b><div class="dislog-mask" data-v-31384c7b></div> <div class="copy-limit-dialog" data-v-31384c7b><div class="close-dialog-btn" data-v-31384c7b></div> <div class="main-content" data-v-31384c7b><span class="tip-message" data-v-31384c7b>
          文档复制为VIP权益，开通VIP可继续复制
        </span> <ul class="list" data-v-31384c7b><li class="xztq-r" data-v-31384c7b>享全站VIP文档下载特权</li> <li class="mfzx-r" data-v-31384c7b>与博主亲密交流特权</li> <li class="eight-count-r" data-v-31384c7b>
            随时随地随心下载
          </li> <li class="gszh-r" data-v-31384c7b>文档多格式转化</li></ul> <span class="buy-vip-btn" data-v-31384c7b><a href="https://ftp.bmp.ovh/imgs/2021/05/dd79da2e8a65b1d5.jpg" target="_blank" rel="noopener noreferrer" data-v-31384c7b>开通VIP, 享受无限制复制特权</a></span></div></div></div><div class="box" style="display:none;" data-v-bb7a82ec>
  春节快乐
  <div class="light" data-v-bb7a82ec><div class="line" data-v-bb7a82ec></div> <div class="light-a" data-v-bb7a82ec><div class="light-b" data-v-bb7a82ec></div> <div class="light-c" data-v-bb7a82ec>
        新
      </div> <div class="ear-a" data-v-bb7a82ec><div class="ear-b" data-v-bb7a82ec></div> <div class="ear-c" data-v-bb7a82ec></div></div></div></div></div><div data-v-50ef6c52><div class="DetailsOpenFlag" style="right:1rem;bottom:9rem;width:2.5rem;height:2.5rem;border-radius:.25rem;line-height:2.5rem;font-size:14px;font-weight:500;display:none;" data-v-50ef6c52>
 展开 

</div></div><div class="kanbanniang" data-v-5775ee02><div class="banniang-container" style="display:;" data-v-5775ee02><div class="messageBox" style="right:68px;bottom:190px;display:none;" data-v-5775ee02>
      欢迎来到 青灯有味
    </div> <div class="operation" style="right:56px;bottom:42px;display:;" data-v-5775ee02><i class="kbnfont kbn-ban-home ban-home" data-v-5775ee02></i> <i class="kbnfont kbn-ban-message message" data-v-5775ee02></i> <i class="kbnfont kbn-ban-close close" data-v-5775ee02></i> <a target="_blank" href="https://vuepress-theme-reco.recoluan.com/views/plugins/kanbanniang.html" data-v-5775ee02><i class="kbnfont kbn-ban-info info" data-v-5775ee02></i></a> <i class="kbnfont kbn-ban-theme skin" style="display:none;" data-v-5775ee02></i></div> <canvas id="banniang" width="150" height="220" class="live2d" style="right:56px;bottom:-8px;opacity:1;" data-v-5775ee02></canvas></div> <div class="showBanNiang" style="display:none;" data-v-5775ee02>
    看板娘
  </div></div><div class="reco-bgm-panel" data-v-39f9e6e0><audio id="bgm" src="http://zscnb.gitee.io/upload/static/audio/五里 - 乌兰巴托的夜.mp3" data-v-39f9e6e0></audio> <div class="reco-float-box" style="bottom:200px;z-index:999999;display:none;" data-v-39f9e6e0 data-v-41bcba48 data-v-39f9e6e0><img src="http://zscnb.gitee.io/upload/static/img/wulan.png" data-v-39f9e6e0></div> <div class="reco-bgm-box" style="left:10px;bottom:10px;z-index:999999;" data-v-39f9e6e0 data-v-41bcba48 data-v-39f9e6e0><div class="reco-bgm-cover" style="background-image:url(http://zscnb.gitee.io/upload/static/img/wulan.png);" data-v-39f9e6e0><div class="mini-operation" style="display:none;" data-v-39f9e6e0><i class="reco-bgm reco-bgm-pause" style="display:none;" data-v-39f9e6e0></i> <i class="reco-bgm reco-bgm-play" style="display:none;" data-v-39f9e6e0></i></div> <div class="falut-message" style="display:none;" data-v-39f9e6e0>
          播放失败
        </div></div> <div class="reco-bgm-info" data-v-39f9e6e0 data-v-41bcba48 data-v-39f9e6e0><div class="info-box" data-v-39f9e6e0><i class="reco-bgm reco-bgm-music music" data-v-39f9e6e0></i>五里-乌兰巴托的夜</div> <div class="info-box" data-v-39f9e6e0><i class="reco-bgm reco-bgm-artist" data-v-39f9e6e0></i>乌兰巴托的夜</div> <div class="reco-bgm-progress" data-v-39f9e6e0><div class="progress-bar" data-v-39f9e6e0><div class="bar" data-v-39f9e6e0></div></div></div> <div class="reco-bgm-operation" data-v-39f9e6e0><i class="reco-bgm reco-bgm-last last" data-v-39f9e6e0></i> <i class="reco-bgm reco-bgm-pause pause" style="display:none;" data-v-39f9e6e0></i> <i class="reco-bgm reco-bgm-play play" data-v-39f9e6e0></i> <i class="reco-bgm reco-bgm-next next" data-v-39f9e6e0></i> <i class="reco-bgm reco-bgm-volume1 volume" data-v-39f9e6e0></i> <i class="reco-bgm reco-bgm-mute mute" style="display:none;" data-v-39f9e6e0></i> <div class="volume-bar" data-v-39f9e6e0><div class="bar" data-v-39f9e6e0></div></div></div></div> <div class="reco-bgm-left-box" data-v-39f9e6e0 data-v-41bcba48 data-v-39f9e6e0><i class="reco-bgm reco-bgm-left" data-v-39f9e6e0></i></div></div></div><div></div><div id="musicPlayer" data-v-b7b63636><!----> <div class="bbox" data-v-b7b63636><div class="pan" style="background-image:url(/assets/img/pan.07613e22.png);" data-v-b7b63636><img src="" alt class="pan_c" data-v-b7b63636></div> <div class="box" style="background-image:url();" data-v-b7b63636><div class="music_shlter_2" style="background-image:url();" data-v-b7b63636></div> <div class="music_shlter" style="background-image:url();" data-v-b7b63636></div> <div class="music_shlter_3" data-v-b7b63636></div> <div class="music_dis" data-v-b7b63636><div class="dis_list" data-v-b7b63636>···</div> <p class="music_title" data-v-b7b63636></p> <p class="music_intro" data-v-b7b63636>歌手: </p> <ul class="music_words" data-v-b7b63636><div class="music_words_box" style="top:0px;" data-v-b7b63636></div></ul></div> <div class="control_box" data-v-b7b63636><div class="control_button" data-v-b7b63636><img src="" alt class="control_icon" data-v-b7b63636></div> <div class="progress" data-v-b7b63636><div class="progress_c" style="width:0%;" data-v-b7b63636><div class="progress_circle" data-v-b7b63636><div class="progress_circle_c" data-v-b7b63636></div></div></div></div></div></div> <video id="music" autoplay="autoplay" src="" name="media" data-v-b7b63636></video></div></div></div></div>
    <script src="/assets/js/app.3af45ec9.js" defer></script><script src="/assets/js/6.5ffa3a3c.js" defer></script><script src="/assets/js/1.60e80d20.js" defer></script><script src="/assets/js/51.075b2486.js" defer></script><script src="/assets/js/36.10d521da.js" defer></script>
  </body>
</html>
